summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Ville Linde <villedevs@gmail.com>2016-05-28 17:46:58 +0300
committer Ville Linde <villedevs@gmail.com>2016-05-28 18:58:54 +0300
commit958731ef5aef0e2357bd03f597e0ec06f893d309 (patch)
treea057c79e7fa3c3d41b88e59a0aa121216f640e08
parent9cf8e8ac0ae259901080f8cfce1ae39a310286c6 (diff)
Added highly experimental SHARC recompiler (disabled by default) [Ville Linde]
-rw-r--r--scripts/src/cpu.lua3
-rw-r--r--src/devices/cpu/drcfe.cpp1
-rw-r--r--src/devices/cpu/drcfe.h1
-rw-r--r--src/devices/cpu/sharc/compute.hxx410
-rw-r--r--src/devices/cpu/sharc/sharc.cpp905
-rw-r--r--src/devices/cpu/sharc/sharc.h440
-rw-r--r--src/devices/cpu/sharc/sharcdma.hxx152
-rw-r--r--src/devices/cpu/sharc/sharcdrc.cpp4909
-rw-r--r--src/devices/cpu/sharc/sharcdsm.cpp4
-rw-r--r--src/devices/cpu/sharc/sharcfe.cpp1830
-rw-r--r--src/devices/cpu/sharc/sharcfe.h81
-rw-r--r--src/devices/cpu/sharc/sharcmem.hxx15
-rw-r--r--src/devices/cpu/sharc/sharcops.hxx1132
13 files changed, 8546 insertions, 1337 deletions
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua
index 1b746fb59bc..054a2bbabee 100644
--- a/scripts/src/cpu.lua
+++ b/scripts/src/cpu.lua
@@ -221,6 +221,9 @@ if (CPUS["ADSP21062"]~=null) then
MAME_DIR .. "src/devices/cpu/sharc/sharcmem.hxx",
MAME_DIR .. "src/devices/cpu/sharc/sharcops.h",
MAME_DIR .. "src/devices/cpu/sharc/sharcops.hxx",
+ MAME_DIR .. "src/devices/cpu/sharc/sharcdrc.cpp",
+ MAME_DIR .. "src/devices/cpu/sharc/sharcfe.cpp",
+ MAME_DIR .. "src/devices/cpu/sharc/sharcfe.h",
}
end
diff --git a/src/devices/cpu/drcfe.cpp b/src/devices/cpu/drcfe.cpp
index 6d2bd09cddf..87478de59e6 100644
--- a/src/devices/cpu/drcfe.cpp
+++ b/src/devices/cpu/drcfe.cpp
@@ -171,6 +171,7 @@ opcode_desc *drc_frontend::describe_one(offs_t curpc, const opcode_desc *prevdes
desc->delayslots = 0;
desc->skipslots = 0;
desc->flags = 0;
+ desc->userflags = 0;
desc->cycles = 0;
memset(desc->regin, 0x00, sizeof(desc->regin));
memset(desc->regout, 0x00, sizeof(desc->regout));
diff --git a/src/devices/cpu/drcfe.h b/src/devices/cpu/drcfe.h
index 67c67067221..09d86b2bd99 100644
--- a/src/devices/cpu/drcfe.h
+++ b/src/devices/cpu/drcfe.h
@@ -113,6 +113,7 @@ struct opcode_desc
UINT8 delayslots; // number of delay slots (for branches)
UINT8 skipslots; // number of skip slots (for branches)
UINT32 flags; // OPFLAG_* opcode flags
+ UINT32 userflags; // core specific flags
UINT32 cycles; // number of cycles needed to execute
// register usage information
diff --git a/src/devices/cpu/sharc/compute.hxx b/src/devices/cpu/sharc/compute.hxx
index 880b368ad1f..4124fadf6a9 100644
--- a/src/devices/cpu/sharc/compute.hxx
+++ b/src/devices/cpu/sharc/compute.hxx
@@ -4,27 +4,27 @@
#include <math.h>
-#define CLEAR_ALU_FLAGS() (m_astat &= ~(AZ|AN|AV|AC|AS|AI))
+#define CLEAR_ALU_FLAGS() (m_core->astat &= ~(AZ|AN|AV|AC|AS|AI))
-#define SET_FLAG_AZ(r) { m_astat |= (((r) == 0) ? AZ : 0); }
-#define SET_FLAG_AN(r) { m_astat |= (((r) & 0x80000000) ? AN : 0); }
-#define SET_FLAG_AC_ADD(r,a,b) { m_astat |= (((UINT32)r < (UINT32)a) ? AC : 0); }
-#define SET_FLAG_AV_ADD(r,a,b) { m_astat |= (((~((a) ^ (b)) & ((a) ^ (r))) & 0x80000000) ? AV : 0); }
-#define SET_FLAG_AC_SUB(r,a,b) { m_astat |= ((!((UINT32)a < (UINT32)b)) ? AC : 0); }
-#define SET_FLAG_AV_SUB(r,a,b) { m_astat |= ((( ((a) ^ (b)) & ((a) ^ (r))) & 0x80000000) ? AV : 0); }
+#define SET_FLAG_AZ(r) { m_core->astat |= (((r) == 0) ? AZ : 0); }
+#define SET_FLAG_AN(r) { m_core->astat |= (((r) & 0x80000000) ? AN : 0); }
+#define SET_FLAG_AC_ADD(r,a,b) { m_core->astat |= (((UINT32)r < (UINT32)a) ? AC : 0); }
+#define SET_FLAG_AV_ADD(r,a,b) { m_core->astat |= (((~((a) ^ (b)) & ((a) ^ (r))) & 0x80000000) ? AV : 0); }
+#define SET_FLAG_AC_SUB(r,a,b) { m_core->astat |= ((!((UINT32)a < (UINT32)b)) ? AC : 0); }
+#define SET_FLAG_AV_SUB(r,a,b) { m_core->astat |= ((( ((a) ^ (b)) & ((a) ^ (r))) & 0x80000000) ? AV : 0); }
#define IS_FLOAT_ZERO(r) ((((r) & 0x7fffffff) == 0))
#define IS_FLOAT_DENORMAL(r) ((((r) & 0x7f800000) == 0) && (((r) & 0x7fffff) != 0))
#define IS_FLOAT_NAN(r) ((((r) & 0x7f800000) == 0x7f800000) && (((r) & 0x7fffff) != 0))
#define IS_FLOAT_INFINITY(r) (((r) & 0x7fffffff) == 0x7f800000)
-#define CLEAR_MULTIPLIER_FLAGS() (m_astat &= ~(MN|MV|MU|MI))
+#define CLEAR_MULTIPLIER_FLAGS() (m_core->astat &= ~(MN|MV|MU|MI))
-#define SET_FLAG_MN(r) { m_astat |= (((r) & 0x80000000) ? MN : 0); }
-#define SET_FLAG_MV(r) { m_astat |= ((((UINT32)((r) >> 32) != 0) && ((UINT32)((r) >> 32) != 0xffffffff)) ? MV : 0); }
+#define SET_FLAG_MN(r) { m_core->astat |= (((r) & 0x80000000) ? MN : 0); }
+#define SET_FLAG_MV(r) { m_core->astat |= ((((UINT32)((r) >> 32) != 0) && ((UINT32)((r) >> 32) != 0xffffffff)) ? MV : 0); }
/* TODO: MU needs 80-bit result */
-#define SET_FLAG_MU(r) { m_astat |= ((((UINT32)((r) >> 32) == 0) && ((UINT32)(r)) != 0) ? MU : 0); }
+#define SET_FLAG_MU(r) { m_core->astat |= ((((UINT32)((r) >> 32) == 0) && ((UINT32)(r)) != 0) ? MU : 0); }
#define FLOAT_SIGN 0x80000000
@@ -115,7 +115,7 @@ void adsp21062_device::compute_add(int rn, int rx, int ry)
{
UINT32 r = REG(rx) + REG(ry);
- if (m_mode1 & MODE1_ALUSAT)
+ if (m_core->mode1 & MODE1_ALUSAT)
fatalerror("SHARC: compute_add: ALU saturation not implemented!\n");
CLEAR_ALU_FLAGS();
@@ -125,7 +125,7 @@ void adsp21062_device::compute_add(int rn, int rx, int ry)
SET_FLAG_AC_ADD(r, REG(rx), REG(ry));
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = Rx - Ry */
@@ -133,7 +133,7 @@ void adsp21062_device::compute_sub(int rn, int rx, int ry)
{
UINT32 r = REG(rx) - REG(ry);
- if (m_mode1 & MODE1_ALUSAT)
+ if (m_core->mode1 & MODE1_ALUSAT)
fatalerror("SHARC: compute_sub: ALU saturation not implemented!\n");
CLEAR_ALU_FLAGS();
@@ -143,16 +143,16 @@ void adsp21062_device::compute_sub(int rn, int rx, int ry)
SET_FLAG_AC_SUB(r, REG(rx), REG(ry));
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = Rx + Ry + CI */
void adsp21062_device::compute_add_ci(int rn, int rx, int ry)
{
- int c = (m_astat & AC) ? 1 : 0;
+ int c = (m_core->astat & AC) ? 1 : 0;
UINT32 r = REG(rx) + REG(ry) + c;
- if (m_mode1 & MODE1_ALUSAT)
+ if (m_core->mode1 & MODE1_ALUSAT)
fatalerror("SHARC: compute_add_ci: ALU saturation not implemented!\n");
CLEAR_ALU_FLAGS();
@@ -162,16 +162,16 @@ void adsp21062_device::compute_add_ci(int rn, int rx, int ry)
SET_FLAG_AC_ADD(r, REG(rx), REG(ry)+c);
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = Rx - Ry + CI - 1 */
void adsp21062_device::compute_sub_ci(int rn, int rx, int ry)
{
- int c = (m_astat & AC) ? 1 : 0;
+ int c = (m_core->astat & AC) ? 1 : 0;
UINT32 r = REG(rx) - REG(ry) + c - 1;
- if (m_mode1 & MODE1_ALUSAT)
+ if (m_core->mode1 & MODE1_ALUSAT)
fatalerror("SHARC: compute_sub_ci: ALU saturation not implemented!\n");
CLEAR_ALU_FLAGS();
@@ -181,7 +181,7 @@ void adsp21062_device::compute_sub_ci(int rn, int rx, int ry)
SET_FLAG_AC_SUB(r, REG(rx), REG(ry)+c-1);
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = Rx AND Ry */
@@ -194,7 +194,7 @@ void adsp21062_device::compute_and(int rn, int rx, int ry)
SET_FLAG_AZ(r);
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* COMP(Rx, Ry) */
@@ -204,21 +204,21 @@ void adsp21062_device::compute_comp(int rx, int ry)
CLEAR_ALU_FLAGS();
if( REG(rx) == REG(ry) )
- m_astat |= AZ;
+ m_core->astat |= AZ;
if( (INT32)REG(rx) < (INT32)REG(ry) )
- m_astat |= AN;
+ m_core->astat |= AN;
// Update ASTAT compare accumulation register
- comp_accum = (m_astat >> 24) & 0xff;
+ comp_accum = (m_core->astat >> 24) & 0xff;
comp_accum >>= 1;
- if ((m_astat & (AZ|AN)) == 0)
+ if ((m_core->astat & (AZ|AN)) == 0)
{
comp_accum |= 0x80;
}
- m_astat &= 0xffffff;
- m_astat |= comp_accum << 24;
+ m_core->astat &= 0xffffff;
+ m_core->astat |= comp_accum << 24;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = PASS Rx */
@@ -229,11 +229,11 @@ void adsp21062_device::compute_pass(int rn, int rx)
REG(rn) = REG(rx);
if (REG(rn) == 0)
- m_astat |= AZ;
+ m_core->astat |= AZ;
if (REG(rn) & 0x80000000)
- m_astat |= AN;
+ m_core->astat |= AN;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = Rx XOR Ry */
@@ -245,7 +245,7 @@ void adsp21062_device::compute_xor(int rn, int rx, int ry)
SET_FLAG_AZ(r);
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = Rx OR Ry */
@@ -257,7 +257,7 @@ void adsp21062_device::compute_or(int rn, int rx, int ry)
SET_FLAG_AZ(r);
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = Rx + 1 */
@@ -273,7 +273,7 @@ void adsp21062_device::compute_inc(int rn, int rx)
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = Rx - 1 */
@@ -289,7 +289,7 @@ void adsp21062_device::compute_dec(int rn, int rx)
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = MIN(Rx, Ry) */
@@ -303,7 +303,7 @@ void adsp21062_device::compute_min(int rn, int rx, int ry)
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = MAX(Rx, Ry) */
@@ -317,7 +317,7 @@ void adsp21062_device::compute_max(int rn, int rx, int ry)
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = -Rx */
@@ -333,7 +333,7 @@ void adsp21062_device::compute_neg(int rn, int rx)
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rn = NOT Rx */
@@ -347,7 +347,7 @@ void adsp21062_device::compute_not(int rn, int rx)
REG(rn) = r;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/*****************************************************************************/
@@ -364,13 +364,13 @@ UINT32 adsp21062_device::SCALB(SHARC_REG rx, int ry)
if (exponent > 127)
{
// overflow
- m_astat |= AV;
+ m_core->astat |= AV;
return sign | FLOAT_INFINITY;
}
else if (exponent < -126)
{
// denormal
- m_astat |= AZ;
+ m_core->astat |= AZ;
return sign;
}
else
@@ -389,12 +389,12 @@ void adsp21062_device::compute_float(int rn, int rx)
// AN
SET_FLAG_AN(REG(rn));
// AZ
- m_astat |= (IS_FLOAT_DENORMAL(REG(rn)) || IS_FLOAT_ZERO(REG(rn))) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_DENORMAL(REG(rn)) || IS_FLOAT_ZERO(REG(rn))) ? AZ : 0;
// AUS
- m_stky |= (IS_FLOAT_DENORMAL(REG(rn))) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(REG(rn))) ? AUS : 0;
/* TODO: AV flag */
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Rn = FIX Fx */
@@ -404,7 +404,7 @@ void adsp21062_device::compute_fix(int rn, int rx)
SHARC_REG r_alu;
r_alu.f = FREG(rx);
- if (m_mode1 & MODE1_TRUNCATE)
+ if (m_core->mode1 & MODE1_TRUNCATE)
{
alu_i = (INT32)(r_alu.f);
}
@@ -418,13 +418,13 @@ void adsp21062_device::compute_fix(int rn, int rx)
// AZ
SET_FLAG_AZ(alu_i);
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
/* TODO: AV flag */
REG(rn) = alu_i;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Rn = FIX Fx BY Ry */
@@ -433,8 +433,8 @@ void adsp21062_device::compute_fix_scaled(int rn, int rx, int ry)
INT32 alu_i;
SHARC_REG r_alu;
- r_alu.r = SCALB(m_r[rx], ry);
- if (m_mode1 & MODE1_TRUNCATE)
+ r_alu.r = SCALB(m_core->r[rx], ry);
+ if (m_core->mode1 & MODE1_TRUNCATE)
{
alu_i = (INT32)(r_alu.f);
}
@@ -448,13 +448,13 @@ void adsp21062_device::compute_fix_scaled(int rn, int rx, int ry)
// AZ
SET_FLAG_AZ(alu_i);
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
/* TODO: AV flag */
REG(rn) = alu_i;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fn = FLOAT Rx BY Ry */
@@ -471,11 +471,11 @@ void adsp21062_device::compute_float_scaled(int rn, int rx, int ry)
// AN
SET_FLAG_AN(REG(rn));
// AZ
- m_astat |= (IS_FLOAT_DENORMAL(REG(rn)) || IS_FLOAT_ZERO(REG(rn))) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_DENORMAL(REG(rn)) || IS_FLOAT_ZERO(REG(rn))) ? AZ : 0;
// AU
- m_stky |= (IS_FLOAT_DENORMAL(REG(rn))) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(REG(rn))) ? AUS : 0;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Rn = LOGB Fx */
@@ -490,20 +490,20 @@ void adsp21062_device::compute_logb(int rn, int rx)
{
REG(rn) = FLOAT_INFINITY;
- m_astat |= AV;
+ m_core->astat |= AV;
}
else if (IS_FLOAT_ZERO(REG(rx)))
{
REG(rn) = FLOAT_SIGN | FLOAT_INFINITY;
- m_astat |= AV;
+ m_core->astat |= AV;
}
else if (IS_FLOAT_NAN(REG(rx)))
{
REG(rn) = 0xffffffff;
- m_astat |= AI;
- m_stky |= AIS;
+ m_core->astat |= AI;
+ m_core->stky |= AIS;
}
else
{
@@ -517,7 +517,7 @@ void adsp21062_device::compute_logb(int rn, int rx)
REG(rn) = exponent;
}
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fn = SCALB Fx BY Fy */
@@ -529,25 +529,25 @@ void adsp21062_device::compute_scalb(int rn, int rx, int ry)
if (IS_FLOAT_NAN(REG(rx)))
{
- m_astat |= AI;
- m_stky |= AIS;
+ m_core->astat |= AI;
+ m_core->stky |= AIS;
REG(rn) = 0xffffffff;
}
else
{
- r.r = SCALB(m_r[rx], ry);
+ r.r = SCALB(m_core->r[rx], ry);
// AN
SET_FLAG_AN(r.r);
// AZ
- m_astat |= IS_FLOAT_ZERO(r.r) ? AZ : 0;
+ m_core->astat |= IS_FLOAT_ZERO(r.r) ? AZ : 0;
// AUS
- m_stky |= (IS_FLOAT_DENORMAL(r.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r.r)) ? AUS : 0;
FREG(rn) = r.f;
}
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fn = Fx + Fy */
@@ -558,20 +558,20 @@ void adsp21062_device::compute_fadd(int rn, int rx, int ry)
CLEAR_ALU_FLAGS();
// AN
- m_astat |= (r.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_DENORMAL(r.r) || IS_FLOAT_ZERO(r.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_DENORMAL(r.r) || IS_FLOAT_ZERO(r.r)) ? AZ : 0;
// AUS
- m_stky |= (IS_FLOAT_DENORMAL(r.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
/* TODO: AV flag */
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
FREG(rn) = r.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
void adsp21062_device::compute_favg(int rn, int rx, int ry)
@@ -581,20 +581,20 @@ void adsp21062_device::compute_favg(int rn, int rx, int ry)
CLEAR_ALU_FLAGS();
// AN
- m_astat |= (r.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_DENORMAL(r.r) || IS_FLOAT_ZERO(r.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_DENORMAL(r.r) || IS_FLOAT_ZERO(r.r)) ? AZ : 0;
// AUS
- m_stky |= (IS_FLOAT_DENORMAL(r.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
/* TODO: AV flag */
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
FREG(rn) = r.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fn = Fx - Fy */
@@ -605,20 +605,20 @@ void adsp21062_device::compute_fsub(int rn, int rx, int ry)
CLEAR_ALU_FLAGS();
// AN
- m_astat |= (r.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_DENORMAL(r.r) || IS_FLOAT_ZERO(r.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_DENORMAL(r.r) || IS_FLOAT_ZERO(r.r)) ? AZ : 0;
// AUS
- m_stky |= (IS_FLOAT_DENORMAL(r.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
/* TODO: AV flag */
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
FREG(rn) = r.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fn = -Fx */
@@ -629,17 +629,17 @@ void adsp21062_device::compute_fneg(int rn, int rx)
CLEAR_ALU_FLAGS();
// AZ
- m_astat |= (IS_FLOAT_ZERO(r.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(r.r)) ? AZ : 0;
// AN
- m_astat |= (r.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r.f < 0.0f) ? AN : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
FREG(rn) = r.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* COMP(Fx, Fy) */
@@ -650,26 +650,26 @@ void adsp21062_device::compute_fcomp(int rx, int ry)
CLEAR_ALU_FLAGS();
// AZ
if( FREG(rx) == FREG(ry) )
- m_astat |= AZ;
+ m_core->astat |= AZ;
// AN
if( FREG(rx) < FREG(ry) )
- m_astat |= AN;
+ m_core->astat |= AN;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
// Update ASTAT compare accumulation register
- comp_accum = (m_astat >> 24) & 0xff;
+ comp_accum = (m_core->astat >> 24) & 0xff;
comp_accum >>= 1;
- if ((m_astat & (AZ|AN)) == 0)
+ if ((m_core->astat & (AZ|AN)) == 0)
{
comp_accum |= 0x80;
}
- m_astat &= 0xffffff;
- m_astat |= comp_accum << 24;
- m_astat |= AF;
+ m_core->astat &= 0xffffff;
+ m_core->astat |= comp_accum << 24;
+ m_core->astat |= AF;
}
/* Fn = ABS(Fx + Fy) */
@@ -680,18 +680,18 @@ void adsp21062_device::compute_fabs_plus(int rn, int rx, int ry)
CLEAR_ALU_FLAGS();
// AZ
- m_astat |= (IS_FLOAT_DENORMAL(r.r) || IS_FLOAT_ZERO(r.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_DENORMAL(r.r) || IS_FLOAT_ZERO(r.r)) ? AZ : 0;
// AUS
- m_stky |= (IS_FLOAT_DENORMAL(r.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
/* TODO: AV flag */
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
FREG(rn) = r.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fn = MAX(Fx, Fy) */
@@ -702,17 +702,17 @@ void adsp21062_device::compute_fmax(int rn, int rx, int ry)
r_alu.f = MAX(FREG(rx), FREG(ry));
CLEAR_ALU_FLAGS();
- m_astat |= (r_alu.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r_alu.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
/* TODO: AV flag */
FREG(rn) = r_alu.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fn = MIN(Fx, Fy) */
@@ -723,17 +723,17 @@ void adsp21062_device::compute_fmin(int rn, int rx, int ry)
r_alu.f = MIN(FREG(rx), FREG(ry));
CLEAR_ALU_FLAGS();
- m_astat |= (r_alu.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r_alu.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
/* TODO: AV flag */
FREG(rn) = r_alu.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fn = CLIP Fx BY Fy */
@@ -761,14 +761,14 @@ void adsp21062_device::compute_fclip(int rn, int rx, int ry)
CLEAR_ALU_FLAGS();
SET_FLAG_AN(r_alu.r);
// AZ
- m_astat |= (IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
FREG(rn) = r_alu.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fn = RECIPS Fx */
@@ -785,17 +785,17 @@ void adsp21062_device::compute_recips(int rn, int rx)
r = 0xffffffff;
// AI
- m_astat |= AI;
+ m_core->astat |= AI;
// AIS
- m_stky |= AIS;
+ m_core->stky |= AIS;
}
else if (IS_FLOAT_ZERO(REG(rx)))
{
// +- Zero
r = (REG(rx) & FLOAT_SIGN) | FLOAT_INFINITY;
- m_astat |= AZ;
+ m_core->astat |= AZ;
}
else
{
@@ -820,17 +820,17 @@ void adsp21062_device::compute_recips(int rn, int rx)
SET_FLAG_AN(REG(rx));
// AZ & AV
- m_astat |= (IS_FLOAT_ZERO(r)) ? AZ : 0;
- m_astat |= (IS_FLOAT_ZERO(REG(rx))) ? AV : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(REG(rx))) ? AV : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
}
// AF
- m_astat |= AF;
+ m_core->astat |= AF;
REG(rn) = r;
}
@@ -867,16 +867,16 @@ void adsp21062_device::compute_rsqrts(int rn, int rx)
CLEAR_ALU_FLAGS();
// AN
- m_astat |= (REG(rx) == 0x80000000) ? AN : 0;
+ m_core->astat |= (REG(rx) == 0x80000000) ? AN : 0;
// AZ & AV
- m_astat |= (IS_FLOAT_ZERO(r)) ? AZ : 0;
- m_astat |= (IS_FLOAT_ZERO(REG(rx))) ? AV : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(REG(rx))) ? AV : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx)) || (REG(rx) & 0x80000000)) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx)) || (REG(rx) & 0x80000000)) ? AI : 0;
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
// AF
- m_astat |= AF;
+ m_core->astat |= AF;
REG(rn) = r;
}
@@ -890,14 +890,14 @@ void adsp21062_device::compute_fpass(int rn, int rx)
CLEAR_ALU_FLAGS();
// AN
- m_astat |= (r.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_ZERO(r.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(r.r)) ? AZ : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
FREG(rn) = r.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fn = ABS Fx */
@@ -908,14 +908,14 @@ void adsp21062_device::compute_fabs(int rn, int rx)
CLEAR_ALU_FLAGS();
// AN
- m_astat |= (r.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_ZERO(r.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(r.r)) ? AZ : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx))) ? AI : 0;
FREG(rn) = r.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/*****************************************************************************/
@@ -950,7 +950,7 @@ void adsp21062_device::compute_mul_ssin(int rn, int rx, int ry)
/* MRF + (signed)Rx * (signed)Ry, integer, no rounding */
UINT32 adsp21062_device::compute_mrf_plus_mul_ssin(int rx, int ry)
{
- UINT64 r = m_mrf + ((INT64)(INT32)REG(rx) * (INT64)(INT32)REG(ry));
+ UINT64 r = m_core->mrf + ((INT64)(INT32)REG(rx) * (INT64)(INT32)REG(ry));
CLEAR_MULTIPLIER_FLAGS();
SET_FLAG_MN((UINT32)r);
@@ -963,7 +963,7 @@ UINT32 adsp21062_device::compute_mrf_plus_mul_ssin(int rx, int ry)
/* MRB + (signed)Rx * (signed)Ry, integer, no rounding */
UINT32 adsp21062_device::compute_mrb_plus_mul_ssin(int rx, int ry)
{
- INT64 r = m_mrb + ((INT64)(INT32)REG(rx) * (INT64)(INT32)REG(ry));
+ INT64 r = m_core->mrb + ((INT64)(INT32)REG(rx) * (INT64)(INT32)REG(ry));
CLEAR_MULTIPLIER_FLAGS();
SET_FLAG_MN((UINT32)r);
@@ -994,11 +994,11 @@ void adsp21062_device::compute_multi_mr_to_reg(int ai, int rk)
{
switch(ai)
{
- case 0: SET_UREG(rk, (UINT32)(m_mrf)); break;
- case 1: SET_UREG(rk, (UINT32)(m_mrf >> 32)); break;
+ case 0: SET_UREG(rk, (UINT32)(m_core->mrf)); break;
+ case 1: SET_UREG(rk, (UINT32)(m_core->mrf >> 32)); break;
case 2: fatalerror("SHARC: tried to load MR2F\n"); break;
- case 4: SET_UREG(rk, (UINT32)(m_mrb)); break;
- case 5: SET_UREG(rk, (UINT32)(m_mrb >> 32)); break;
+ case 4: SET_UREG(rk, (UINT32)(m_core->mrb)); break;
+ case 5: SET_UREG(rk, (UINT32)(m_core->mrb >> 32)); break;
case 6: fatalerror("SHARC: tried to load MR2B\n"); break;
default: fatalerror("SHARC: unknown ai %d in mr_to_reg\n", ai);
}
@@ -1010,11 +1010,11 @@ void adsp21062_device::compute_multi_reg_to_mr(int ai, int rk)
{
switch(ai)
{
- case 0: m_mrf &= ~0xffffffff; m_mrf |= GET_UREG(rk); break;
- case 1: m_mrf &= 0xffffffff; m_mrf |= (UINT64)(GET_UREG(rk)) << 32; break;
+ case 0: m_core->mrf &= ~0xffffffff; m_core->mrf |= GET_UREG(rk); break;
+ case 1: m_core->mrf &= 0xffffffff; m_core->mrf |= (UINT64)(GET_UREG(rk)) << 32; break;
case 2: fatalerror("SHARC: tried to write MR2F\n"); break;
- case 4: m_mrb &= ~0xffffffff; m_mrb |= GET_UREG(rk); break;
- case 5: m_mrb &= 0xffffffff; m_mrb |= (UINT64)(GET_UREG(rk)) << 32; break;
+ case 4: m_core->mrb &= ~0xffffffff; m_core->mrb |= GET_UREG(rk); break;
+ case 5: m_core->mrb &= 0xffffffff; m_core->mrb |= (UINT64)(GET_UREG(rk)) << 32; break;
case 6: fatalerror("SHARC: tried to write MR2B\n"); break;
default: fatalerror("SHARC: unknown ai %d in reg_to_mr\n", ai);
}
@@ -1031,27 +1031,27 @@ void adsp21062_device::compute_dual_add_sub(int ra, int rs, int rx, int ry)
CLEAR_ALU_FLAGS();
if (r_add == 0 || r_sub == 0)
{
- m_astat |= AZ;
+ m_core->astat |= AZ;
}
if (r_add & 0x80000000 || r_sub & 0x80000000)
{
- m_astat |= AN;
+ m_core->astat |= AN;
}
if (((~(REG(rx) ^ REG(ry)) & (REG(rx) ^ r_add)) & 0x80000000) ||
(( (REG(rx) ^ REG(ry)) & (REG(rx) ^ r_sub)) & 0x80000000))
{
- m_astat |= AV;
+ m_core->astat |= AV;
}
if (((UINT32)r_add < (UINT32)REG(rx)) ||
(!((UINT32)r_sub < (UINT32)REG(rx))))
{
- m_astat |= AC;
+ m_core->astat |= AC;
}
REG(ra) = r_add;
REG(rs) = r_sub;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rm = (signed)Rxm * (signed)Rym, fractional, rounding, Ra = Rxa + Rya */
@@ -1076,7 +1076,7 @@ void adsp21062_device::compute_mul_ssfr_add(int rm, int rxm, int rym, int ra, in
REG(rm) = r_mul;
REG(ra) = r_add;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
/* Rm = (signed)Rxm * (signed)Rym, fractional, rounding, Ra = Rxa - Rya */
@@ -1101,7 +1101,7 @@ void adsp21062_device::compute_mul_ssfr_sub(int rm, int rxm, int rym, int ra, in
REG(rm) = r_mul;
REG(ra) = r_sub;
- m_astat &= ~AF;
+ m_core->astat &= ~AF;
}
@@ -1116,22 +1116,22 @@ void adsp21062_device::compute_dual_fadd_fsub(int ra, int rs, int rx, int ry)
CLEAR_ALU_FLAGS();
// AN
- m_astat |= ((r_add.f < 0.0f) || (r_sub.f < 0.0f)) ? AN : 0;
+ m_core->astat |= ((r_add.f < 0.0f) || (r_sub.f < 0.0f)) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_DENORMAL(r_add.r) || IS_FLOAT_ZERO(r_add.r) ||
+ m_core->astat |= (IS_FLOAT_DENORMAL(r_add.r) || IS_FLOAT_ZERO(r_add.r) ||
IS_FLOAT_DENORMAL(r_sub.r) || IS_FLOAT_ZERO(r_sub.r)) ? AZ : 0;
// AUS
- m_stky |= (IS_FLOAT_DENORMAL(r_add.r) || IS_FLOAT_DENORMAL(r_sub.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_add.r) || IS_FLOAT_DENORMAL(r_sub.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(rx)) || IS_FLOAT_NAN(REG(ry))) ? AI : 0;
/* TODO: AV flag */
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
FREG(ra) = r_add.f;
FREG(rs) = r_sub.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fm = Fxm * Fym, Fa = Fxa + Fya */
@@ -1148,21 +1148,21 @@ void adsp21062_device::compute_fmul_fadd(int fm, int fxm, int fym, int fa, int f
/* TODO: MI flag */
CLEAR_ALU_FLAGS();
- m_astat |= (r_add.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r_add.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_DENORMAL(r_add.r) || IS_FLOAT_ZERO(r_add.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_DENORMAL(r_add.r) || IS_FLOAT_ZERO(r_add.r)) ? AZ : 0;
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_add.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_add.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(fxa)) || IS_FLOAT_NAN(REG(fya))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(fxa)) || IS_FLOAT_NAN(REG(fya))) ? AI : 0;
/* TODO: AV flag */
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
FREG(fm) = r_mul.f;
FREG(fa) = r_add.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fm = Fxm * Fym, Fa = Fxa - Fya */
@@ -1179,21 +1179,21 @@ void adsp21062_device::compute_fmul_fsub(int fm, int fxm, int fym, int fa, int f
/* TODO: MI flag */
CLEAR_ALU_FLAGS();
- m_astat |= (r_sub.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r_sub.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_DENORMAL(r_sub.r) || IS_FLOAT_ZERO(r_sub.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_DENORMAL(r_sub.r) || IS_FLOAT_ZERO(r_sub.r)) ? AZ : 0;
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_sub.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_sub.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(fxa)) || IS_FLOAT_NAN(REG(fya))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(fxa)) || IS_FLOAT_NAN(REG(fya))) ? AI : 0;
/* TODO: AV flag */
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
FREG(fm) = r_mul.f;
FREG(fa) = r_sub.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fm = Fxm * Fym, Fa = FLOAT Fxa BY Fya */
@@ -1214,16 +1214,16 @@ void adsp21062_device::compute_fmul_float_scaled(int fm, int fxm, int fym, int f
/* TODO: MI flag */
CLEAR_ALU_FLAGS();
- m_astat |= (r_alu.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r_alu.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_DENORMAL(r_alu.r) || IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_DENORMAL(r_alu.r) || IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
/* TODO: set AV if overflowed */
FREG(fm) = r_mul.f;
FREG(fa) = r_alu.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fm = Fxm * Fym, Fa = FIX Fxa BY Fya */
@@ -1233,9 +1233,9 @@ void adsp21062_device::compute_fmul_fix_scaled(int fm, int fxm, int fym, int fa,
SHARC_REG r_mul, r_alu;
r_mul.f = FREG(fxm) * FREG(fym);
- r_alu.r = SCALB(m_r[fxa], fya);
+ r_alu.r = SCALB(m_core->r[fxa], fya);
- if (m_mode1 & MODE1_TRUNCATE)
+ if (m_core->mode1 & MODE1_TRUNCATE)
{
alu_i = (INT32)(r_alu.f);
}
@@ -1255,14 +1255,14 @@ void adsp21062_device::compute_fmul_fix_scaled(int fm, int fxm, int fym, int fa,
// AZ
SET_FLAG_AZ(alu_i);
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(fxa))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(fxa))) ? AI : 0;
/* TODO: AV flag */
FREG(fm) = r_mul.f;
REG(fa) = alu_i; // TODO: check this, should be RA?
- m_astat |= AF;
+ m_core->astat |= AF;
}
void adsp21062_device::compute_fmul_avg(int fm, int fxm, int fym, int fa, int fxa, int fya)
@@ -1273,7 +1273,7 @@ void adsp21062_device::compute_fmul_avg(int fm, int fxm, int fym, int fa, int fx
r_alu.f = (FREG(fxa) * FREG(fya))/((float) 2.0);
/* TODO: are flags right for this? */
- if (m_mode1 & MODE1_TRUNCATE)
+ if (m_core->mode1 & MODE1_TRUNCATE)
{
alu_i = (INT32)(r_alu.f);
}
@@ -1293,14 +1293,14 @@ void adsp21062_device::compute_fmul_avg(int fm, int fxm, int fym, int fa, int fx
// AZ
SET_FLAG_AZ(alu_i);
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(fxa))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(fxa))) ? AI : 0;
/* TODO: AV flag */
FREG(fm) = r_mul.f;
REG(fa) = alu_i;
- m_astat |= AF;
+ m_core->astat |= AF;
}
/* Fm = Fxm * Fym, Fa = MAX(Fxa, Fya) */
@@ -1318,18 +1318,18 @@ void adsp21062_device::compute_fmul_fmax(int fm, int fxm, int fym, int fa, int f
/* TODO: MI flag */
CLEAR_ALU_FLAGS();
- m_astat |= (r_alu.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r_alu.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(fxa)) || IS_FLOAT_NAN(REG(fya))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(fxa)) || IS_FLOAT_NAN(REG(fya))) ? AI : 0;
/* TODO: AV flag */
FREG(fm) = r_mul.f;
FREG(fa) = r_alu.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
@@ -1348,18 +1348,18 @@ void adsp21062_device::compute_fmul_fmin(int fm, int fxm, int fym, int fa, int f
/* TODO: MI flag */
CLEAR_ALU_FLAGS();
- m_astat |= (r_alu.f < 0.0f) ? AN : 0;
+ m_core->astat |= (r_alu.f < 0.0f) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
+ m_core->astat |= (IS_FLOAT_ZERO(r_alu.r)) ? AZ : 0;
// AU
- m_stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_alu.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(fxa)) || IS_FLOAT_NAN(REG(fya))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(fxa)) || IS_FLOAT_NAN(REG(fya))) ? AI : 0;
/* TODO: AV flag */
FREG(fm) = r_mul.f;
FREG(fa) = r_alu.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
@@ -1380,21 +1380,21 @@ void adsp21062_device::compute_fmul_dual_fadd_fsub(int fm, int fxm, int fym, int
CLEAR_ALU_FLAGS();
// AN
- m_astat |= ((r_add.r < 0.0f) || (r_sub.r < 0.0f)) ? AN : 0;
+ m_core->astat |= ((r_add.r < 0.0f) || (r_sub.r < 0.0f)) ? AN : 0;
// AZ
- m_astat |= (IS_FLOAT_DENORMAL(r_add.r) || IS_FLOAT_ZERO(r_add.r) ||
+ m_core->astat |= (IS_FLOAT_DENORMAL(r_add.r) || IS_FLOAT_ZERO(r_add.r) ||
IS_FLOAT_DENORMAL(r_sub.r) || IS_FLOAT_ZERO(r_sub.r)) ? AZ : 0;
// AUS
- m_stky |= (IS_FLOAT_DENORMAL(r_add.r) || IS_FLOAT_DENORMAL(r_sub.r)) ? AUS : 0;
+ m_core->stky |= (IS_FLOAT_DENORMAL(r_add.r) || IS_FLOAT_DENORMAL(r_sub.r)) ? AUS : 0;
// AI
- m_astat |= (IS_FLOAT_NAN(REG(fxa)) || IS_FLOAT_NAN(REG(fya))) ? AI : 0;
+ m_core->astat |= (IS_FLOAT_NAN(REG(fxa)) || IS_FLOAT_NAN(REG(fya))) ? AI : 0;
/* TODO: AV flag */
// AIS
- if (m_astat & AI) m_stky |= AIS;
+ if (m_core->astat & AI) m_core->stky |= AIS;
FREG(fm) = r_mul.f;
FREG(fa) = r_add.f;
FREG(fs) = r_sub.f;
- m_astat |= AF;
+ m_core->astat |= AF;
}
diff --git a/src/devices/cpu/sharc/sharc.cpp b/src/devices/cpu/sharc/sharc.cpp
index 3c4cadf5386..f5336be8499 100644
--- a/src/devices/cpu/sharc/sharc.cpp
+++ b/src/devices/cpu/sharc/sharc.cpp
@@ -1,6 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Ville Linde
-/* Analog Devices ADSP-2106x SHARC emulator v2.0
+/* Analog Devices ADSP-2106x SHARC emulator v3.0
Written by Ville Linde
*/
@@ -8,6 +8,19 @@
#include "emu.h"
#include "debugger.h"
#include "sharc.h"
+#include "sharcfe.h"
+
+
+#define ENABLE_DRC 0
+#define DISABLE_FAST_REGISTERS 1
+
+
+
+#define CACHE_SIZE (2 * 1024 * 1024)
+#define COMPILE_BACKWARDS_BYTES 128
+#define COMPILE_FORWARDS_BYTES 512
+#define COMPILE_MAX_INSTRUCTIONS ((COMPILE_BACKWARDS_BYTES/4) + (COMPILE_FORWARDS_BYTES/4))
+#define COMPILE_MAX_SEQUENCE 64
enum
@@ -20,7 +33,7 @@ enum
SHARC_R8, SHARC_R9, SHARC_R10, SHARC_R11,
SHARC_R12, SHARC_R13, SHARC_R14, SHARC_R15,
SHARC_SYSCON, SHARC_SYSSTAT, SHARC_MRF, SHARC_MRB,
- SHARC_STSTKP, SHARC_PCSTKP, SHARC_LSTKP,
+ SHARC_STSTKP, SHARC_PCSTKP, SHARC_LSTKP, SHARC_CURLCNTR,
SHARC_FADDR, SHARC_DADDR,
SHARC_I0, SHARC_I1, SHARC_I2, SHARC_I3,
SHARC_I4, SHARC_I5, SHARC_I6, SHARC_I7,
@@ -60,6 +73,9 @@ adsp21062_device::adsp21062_device(const machine_config &mconfig, const char *ta
, m_program_config("program", ENDIANNESS_LITTLE, 64, 24, -3, ADDRESS_MAP_NAME(internal_pgm))
, m_data_config("data", ENDIANNESS_LITTLE, 32, 32, -2)
, m_boot_mode(BOOT_MODE_HOST)
+ , m_cache(CACHE_SIZE + sizeof(sharc_internal_state))
+ , m_drcuml(nullptr)
+ , m_drcfe(nullptr)
{
}
@@ -73,27 +89,27 @@ offs_t adsp21062_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8
void adsp21062_device::CHANGE_PC(UINT32 newpc)
{
- m_pc = newpc;
- m_daddr = newpc;
- m_faddr = newpc+1;
- m_nfaddr = newpc+2;
+ m_core->pc = newpc;
+ m_core->daddr = newpc;
+ m_core->faddr = newpc+1;
+ m_core->nfaddr = newpc+2;
}
void adsp21062_device::CHANGE_PC_DELAYED(UINT32 newpc)
{
- m_nfaddr = newpc;
+ m_core->nfaddr = newpc;
- m_delay_slot1 = m_pc;
- m_delay_slot2 = m_daddr;
+ m_core->delay_slot1 = m_core->pc;
+ m_core->delay_slot2 = m_core->daddr;
}
TIMER_CALLBACK_MEMBER(adsp21062_device::sharc_iop_delayed_write_callback)
{
- switch (m_iop_delayed_reg)
+ switch (m_core->iop_delayed_reg)
{
case 0x1c:
{
- if (m_iop_delayed_data & 0x1)
+ if (m_core->iop_delayed_data & 0x1)
{
sharc_dma_exec(6);
}
@@ -102,25 +118,25 @@ TIMER_CALLBACK_MEMBER(adsp21062_device::sharc_iop_delayed_write_callback)
case 0x1d:
{
- if (m_iop_delayed_data & 0x1)
+ if (m_core->iop_delayed_data & 0x1)
{
sharc_dma_exec(7);
}
break;
}
- default: fatalerror("SHARC: sharc_iop_delayed_write: unknown IOP register %02X\n", m_iop_delayed_reg);
+ default: fatalerror("SHARC: sharc_iop_delayed_write: unknown IOP register %02X\n", m_core->iop_delayed_reg);
}
- m_delayed_iop_timer->adjust(attotime::never, 0);
+ m_core->delayed_iop_timer->adjust(attotime::never, 0);
}
void adsp21062_device::sharc_iop_delayed_w(UINT32 reg, UINT32 data, int cycles)
{
- m_iop_delayed_reg = reg;
- m_iop_delayed_data = data;
+ m_core->iop_delayed_reg = reg;
+ m_core->iop_delayed_data = data;
- m_delayed_iop_timer->adjust(cycles_to_attotime(cycles), 0);
+ m_core->delayed_iop_timer->adjust(cycles_to_attotime(cycles), 0);
}
@@ -133,9 +149,9 @@ UINT32 adsp21062_device::sharc_iop_r(UINT32 address)
case 0x37: // DMA status
{
- return m_dma_status;
+ return m_core->dma_status;
}
- default: fatalerror("sharc_iop_r: Unimplemented IOP reg %02X at %08X\n", address, m_pc);
+ default: fatalerror("sharc_iop_r: Unimplemented IOP reg %02X at %08X\n", address, m_core->pc);
}
}
@@ -148,24 +164,24 @@ void adsp21062_device::sharc_iop_w(UINT32 address, UINT32 data)
case 0x04: // External port DMA buffer 0
/* TODO: Last Bronx uses this to init the program, int_index however is 0? */
{
- external_dma_write(m_extdma_shift,data);
- m_extdma_shift++;
- if(m_extdma_shift == 3)
- m_extdma_shift = 0;
+ external_dma_write(m_core->extdma_shift,data);
+ m_core->extdma_shift++;
+ if(m_core->extdma_shift == 3)
+ m_core->extdma_shift = 0;
#if 0
- UINT64 r = pm_read48(m_dma[6].int_index);
+ UINT64 r = pm_read48(m_core->dma[6].int_index);
- r &= ~((UINT64)(0xffff) << (m_extdma_shift*16));
- r |= ((UINT64)data & 0xffff) << (m_extdma_shift*16);
+ r &= ~((UINT64)(0xffff) << (m_core->extdma_shift*16));
+ r |= ((UINT64)data & 0xffff) << (m_core->extdma_shift*16);
- pm_write48(m_dma[6].int_index, r);
+ pm_write48(m_core->dma[6].int_index, r);
- m_extdma_shift++;
- if (m_extdma_shift == 3)
+ m_core->extdma_shift++;
+ if (m_core->extdma_shift == 3)
{
- m_extdma_shift = 0;
- m_dma[6].int_index ++;
+ m_core->extdma_shift = 0;
+ m_core->dma[6].int_index ++;
}
#endif
}
@@ -186,40 +202,40 @@ void adsp21062_device::sharc_iop_w(UINT32 address, UINT32 data)
// DMA 6
case 0x1c:
{
- m_dma[6].control = data;
+ m_core->dma[6].control = data;
sharc_iop_delayed_w(0x1c, data, 1);
break;
}
case 0x20: break;
- case 0x40: m_dma[6].int_index = data; return;
- case 0x41: m_dma[6].int_modifier = data; return;
- case 0x42: m_dma[6].int_count = data; return;
- case 0x43: m_dma[6].chain_ptr = data; return;
- case 0x44: m_dma[6].gen_purpose = data; return;
- case 0x45: m_dma[6].ext_index = data; return;
- case 0x46: m_dma[6].ext_modifier = data; return;
- case 0x47: m_dma[6].ext_count = data; return;
+ case 0x40: m_core->dma[6].int_index = data; return;
+ case 0x41: m_core->dma[6].int_modifier = data; return;
+ case 0x42: m_core->dma[6].int_count = data; return;
+ case 0x43: m_core->dma[6].chain_ptr = data; return;
+ case 0x44: m_core->dma[6].gen_purpose = data; return;
+ case 0x45: m_core->dma[6].ext_index = data; return;
+ case 0x46: m_core->dma[6].ext_modifier = data; return;
+ case 0x47: m_core->dma[6].ext_count = data; return;
// DMA 7
case 0x1d:
{
- m_dma[7].control = data;
+ m_core->dma[7].control = data;
sharc_iop_delayed_w(0x1d, data, 30);
break;
}
- case 0x48: m_dma[7].int_index = data; return;
- case 0x49: m_dma[7].int_modifier = data; return;
- case 0x4a: m_dma[7].int_count = data; return;
- case 0x4b: m_dma[7].chain_ptr = data; return;
- case 0x4c: m_dma[7].gen_purpose = data; return;
- case 0x4d: m_dma[7].ext_index = data; return;
- case 0x4e: m_dma[7].ext_modifier = data; return;
- case 0x4f: m_dma[7].ext_count = data; return;
+ case 0x48: m_core->dma[7].int_index = data; return;
+ case 0x49: m_core->dma[7].int_modifier = data; return;
+ case 0x4a: m_core->dma[7].int_count = data; return;
+ case 0x4b: m_core->dma[7].chain_ptr = data; return;
+ case 0x4c: m_core->dma[7].gen_purpose = data; return;
+ case 0x4d: m_core->dma[7].ext_index = data; return;
+ case 0x4e: m_core->dma[7].ext_modifier = data; return;
+ case 0x4f: m_core->dma[7].ext_count = data; return;
- default: fatalerror("sharc_iop_w: Unimplemented IOP reg %02X, %08X at %08X\n", address, data, m_pc);
+ default: fatalerror("sharc_iop_w: Unimplemented IOP reg %02X, %08X at %08X\n", address, data, m_core->pc);
}
}
@@ -270,7 +286,7 @@ void adsp21062_device::external_iop_write(UINT32 address, UINT32 data)
{
if (data != 0)
{
- m_dma[6].control = data;
+ m_core->dma[6].control = data;
}
}
else
@@ -287,27 +303,27 @@ void adsp21062_device::external_dma_write(UINT32 address, UINT64 data)
first internal RAM location, before they are used by the DMA controller.
*/
- switch ((m_dma[6].control >> 6) & 0x3)
+ switch ((m_core->dma[6].control >> 6) & 0x3)
{
case 2: // 16/48 packing
{
int shift = address % 3;
- UINT64 r = pm_read48((m_dma[6].int_index & 0x1ffff) | 0x20000);
+ UINT64 r = pm_read48((m_core->dma[6].int_index & 0x1ffff) | 0x20000);
r &= ~((UINT64)(0xffff) << (shift*16));
r |= (data & 0xffff) << (shift*16);
- pm_write48((m_dma[6].int_index & 0x1ffff) | 0x20000, r);
+ pm_write48((m_core->dma[6].int_index & 0x1ffff) | 0x20000, r);
if (shift == 2)
{
- m_dma[6].int_index += m_dma[6].int_modifier;
+ m_core->dma[6].int_index += m_core->dma[6].int_modifier;
}
break;
}
default:
{
- fatalerror("sharc_external_dma_write: unimplemented packing mode %d\n", (m_dma[6].control >> 6) & 0x3);
+ fatalerror("sharc_external_dma_write: unimplemented packing mode %d\n", (m_core->dma[6].control >> 6) & 0x3);
}
}
}
@@ -315,8 +331,12 @@ void adsp21062_device::external_dma_write(UINT32 address, UINT64 data)
void adsp21062_device::device_start()
{
int saveindex;
+
+ m_core = (sharc_internal_state *)m_cache.alloc_near(sizeof(sharc_internal_state));
+ memset(m_core, 0, sizeof(sharc_internal_state));
m_program = &space(AS_PROGRAM);
+ m_direct = &m_program->direct();
m_data = &space(AS_DATA);
build_opcode_table();
@@ -324,9 +344,107 @@ void adsp21062_device::device_start()
m_internal_ram_block0 = &m_internal_ram[0];
m_internal_ram_block1 = &m_internal_ram[0x20000/2];
- m_delayed_iop_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(adsp21062_device::sharc_iop_delayed_write_callback), this));
+ // init UML generator
+ UINT32 umlflags = 0;
+ m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, umlflags, 1, 24, 0);
- for (auto & elem : m_dma_op)
+ // add UML symbols
+ m_drcuml->symbol_add(&m_core->pc, sizeof(m_core->pc), "pc");
+ m_drcuml->symbol_add(&m_core->icount, sizeof(m_core->icount), "icount");
+
+ for (int i=0; i < 16; i++)
+ {
+ char buf[10];
+ sprintf(buf, "r%d", i);
+ m_drcuml->symbol_add(&m_core->r[i], sizeof(m_core->r[i]), buf);
+
+ if (i < 8)
+ {
+ sprintf(buf, "dag_i%d", i);
+ m_drcuml->symbol_add(&m_core->dag1.i[i & 7], sizeof(m_core->dag1.i[i & 7]), buf);
+ sprintf(buf, "dag_m%d", i);
+ m_drcuml->symbol_add(&m_core->dag1.m[i & 7], sizeof(m_core->dag1.m[i & 7]), buf);
+ sprintf(buf, "dag_l%d", i);
+ m_drcuml->symbol_add(&m_core->dag1.l[i & 7], sizeof(m_core->dag1.l[i & 7]), buf);
+ sprintf(buf, "dag_b%d", i);
+ m_drcuml->symbol_add(&m_core->dag1.b[i & 7], sizeof(m_core->dag1.b[i & 7]), buf);
+ }
+ else
+ {
+ sprintf(buf, "dag_i%d", i);
+ m_drcuml->symbol_add(&m_core->dag2.i[i & 7], sizeof(m_core->dag2.i[i & 7]), buf);
+ sprintf(buf, "dag_m%d", i);
+ m_drcuml->symbol_add(&m_core->dag2.m[i & 7], sizeof(m_core->dag2.m[i & 7]), buf);
+ sprintf(buf, "dag_l%d", i);
+ m_drcuml->symbol_add(&m_core->dag2.l[i & 7], sizeof(m_core->dag2.l[i & 7]), buf);
+ sprintf(buf, "dag_b%d", i);
+ m_drcuml->symbol_add(&m_core->dag2.b[i & 7], sizeof(m_core->dag2.b[i & 7]), buf);
+ }
+ }
+
+ m_drcuml->symbol_add(&m_core->astat, sizeof(m_core->astat), "astat");
+ m_drcuml->symbol_add(&m_core->mode1, sizeof(m_core->mode1), "mode1");
+ m_drcuml->symbol_add(&m_core->mode2, sizeof(m_core->mode2), "mode2");
+ m_drcuml->symbol_add(&m_core->lcntr, sizeof(m_core->lcntr), "lcntr");
+ m_drcuml->symbol_add(&m_core->curlcntr, sizeof(m_core->curlcntr), "curlcntr");
+ m_drcuml->symbol_add(&m_core->imask, sizeof(m_core->imask), "imask");
+ m_drcuml->symbol_add(&m_core->imaskp, sizeof(m_core->imaskp), "imaskp");
+ m_drcuml->symbol_add(&m_core->irptl, sizeof(m_core->irptl), "irptl");
+ m_drcuml->symbol_add(&m_core->ustat1, sizeof(m_core->ustat1), "ustat1");
+ m_drcuml->symbol_add(&m_core->ustat2, sizeof(m_core->ustat2), "ustat2");
+ m_drcuml->symbol_add(&m_core->stky, sizeof(m_core->stky), "stky");
+
+ m_drcuml->symbol_add(&m_core->astat_drc.az, sizeof(m_core->astat_drc.az), "astat_az");
+ m_drcuml->symbol_add(&m_core->astat_drc.ac, sizeof(m_core->astat_drc.ac), "astat_ac");
+ m_drcuml->symbol_add(&m_core->astat_drc.an, sizeof(m_core->astat_drc.an), "astat_an");
+ m_drcuml->symbol_add(&m_core->astat_drc.av, sizeof(m_core->astat_drc.av), "astat_av");
+ m_drcuml->symbol_add(&m_core->astat_drc.ai, sizeof(m_core->astat_drc.ai), "astat_ai");
+ m_drcuml->symbol_add(&m_core->astat_drc.as, sizeof(m_core->astat_drc.as), "astat_as");
+ m_drcuml->symbol_add(&m_core->astat_drc.mv, sizeof(m_core->astat_drc.mv), "astat_mv");
+ m_drcuml->symbol_add(&m_core->astat_drc.mn, sizeof(m_core->astat_drc.mn), "astat_mn");
+ m_drcuml->symbol_add(&m_core->astat_drc.mu, sizeof(m_core->astat_drc.mu), "astat_mu");
+ m_drcuml->symbol_add(&m_core->astat_drc.mi, sizeof(m_core->astat_drc.mi), "astat_mi");
+ m_drcuml->symbol_add(&m_core->astat_drc.sz, sizeof(m_core->astat_drc.sz), "astat_sz");
+ m_drcuml->symbol_add(&m_core->astat_drc.sv, sizeof(m_core->astat_drc.sv), "astat_sv");
+ m_drcuml->symbol_add(&m_core->astat_drc.ss, sizeof(m_core->astat_drc.ss), "astat_ss");
+
+ m_drcuml->symbol_add(&m_core->arg0, sizeof(m_core->arg0), "arg0");
+ m_drcuml->symbol_add(&m_core->arg1, sizeof(m_core->arg1), "arg1");
+ m_drcuml->symbol_add(&m_core->arg2, sizeof(m_core->arg2), "arg2");
+ m_drcuml->symbol_add(&m_core->arg3, sizeof(m_core->arg3), "arg3");
+
+ m_drcuml->symbol_add(&m_core->dreg_temp, sizeof(m_core->dreg_temp), "dreg_temp");
+ m_drcuml->symbol_add(&m_core->lstkp, sizeof(m_core->lstkp), "lstkp");
+ m_drcuml->symbol_add(&m_core->px, sizeof(m_core->px), "px");
+
+ m_drcfe = std::make_unique<sharc_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, COMPILE_MAX_SEQUENCE);
+
+ for (int i = 0; i < 16; i++)
+ {
+ m_regmap[i] = uml::mem(&m_core->r[i]);
+ }
+
+ // I0-3 used by the DRC, rest can be assigned to fast registers
+ if (!DISABLE_FAST_REGISTERS)
+ {
+ drcbe_info beinfo;
+ m_drcuml->get_backend_info(beinfo);
+ if (beinfo.direct_iregs > 4)
+ m_regmap[0] = uml::I4;
+ if (beinfo.direct_iregs > 5)
+ m_regmap[1] = uml::I5;
+ if (beinfo.direct_iregs > 6)
+ m_regmap[2] = uml::I6;
+ if (beinfo.direct_iregs > 7)
+ m_regmap[3] = uml::I7;
+ }
+
+ m_cache_dirty = true;
+
+
+ m_core->delayed_iop_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(adsp21062_device::sharc_iop_delayed_write_callback), this));
+
+ for (auto & elem : m_core->dma_op)
{
elem.src = 0;
elem.dst = 0;
@@ -343,32 +461,32 @@ void adsp21062_device::device_start()
for (int i=0; i < 16; i++)
{
- m_r[i].r = 0;
- m_reg_alt[i].r = 0;
+ m_core->r[i].r = 0;
+ m_core->reg_alt[i].r = 0;
}
- m_mrf = 0;
- m_mrb = 0;
- for (auto & elem : m_pcstack)
+ m_core->mrf = 0;
+ m_core->mrb = 0;
+ for (auto & elem : m_core->pcstack)
{
elem = 0;
}
for (int i=0; i < 6; i++)
{
- m_lcstack[i] = 0;
- m_lastack[i] = 0;
+ m_core->lcstack[i] = 0;
+ m_core->lastack[i] = 0;
}
- m_pcstk = 0;
- m_laddr.addr = m_laddr.code = m_laddr.loop_type = 0;
- m_curlcntr = 0;
- m_lcntr = 0;
+ m_core->pcstk = 0;
+ m_core->laddr.addr = m_core->laddr.code = m_core->laddr.loop_type = 0;
+ m_core->curlcntr = 0;
+ m_core->lcntr = 0;
for (int i=0; i < 8; i++)
{
- m_dag1.i[i] = m_dag1.m[i] = m_dag1.b[i] = m_dag1.l[i] = 0;
- m_dag2.i[i] = m_dag2.m[i] = m_dag2.b[i] = m_dag2.l[i] = 0;
- m_dag1_alt.i[i] = m_dag1_alt.m[i] = m_dag1_alt.b[i] = m_dag1_alt.l[i] = 0;
- m_dag2_alt.i[i] = m_dag2_alt.m[i] = m_dag2_alt.b[i] = m_dag2_alt.l[i] = 0;
+ m_core->dag1.i[i] = m_core->dag1.m[i] = m_core->dag1.b[i] = m_core->dag1.l[i] = 0;
+ m_core->dag2.i[i] = m_core->dag2.m[i] = m_core->dag2.b[i] = m_core->dag2.l[i] = 0;
+ m_core->dag1_alt.i[i] = m_core->dag1_alt.m[i] = m_core->dag1_alt.b[i] = m_core->dag1_alt.l[i] = 0;
+ m_core->dag2_alt.i[i] = m_core->dag2_alt.m[i] = m_core->dag2_alt.b[i] = m_core->dag2_alt.l[i] = 0;
}
- for (auto & elem : m_dma)
+ for (auto & elem : m_core->dma)
{
elem.control = 0;
elem.int_index = 0;
@@ -380,261 +498,265 @@ void adsp21062_device::device_start()
elem.ext_modifier = 0;
elem.ext_count = 0;
}
- m_mode1 = 0;
- m_mode2 = 0;
- m_astat = 0;
- m_irptl = 0;
- m_imask = 0;
- m_imaskp = 0;
- m_ustat1 = 0;
- m_ustat2 = 0;
- m_flag[0] = m_flag[1] = m_flag[2] = m_flag[3] = 0;
- m_syscon = 0;
- m_sysstat = 0;
- for (auto & elem : m_status_stack)
+ m_core->mode1 = 0;
+ m_core->mode2 = 0;
+ m_core->astat = 0;
+ m_core->irptl = 0;
+ m_core->imask = 0;
+ m_core->imaskp = 0;
+ m_core->ustat1 = 0;
+ m_core->ustat2 = 0;
+ m_core->flag[0] = m_core->flag[1] = m_core->flag[2] = m_core->flag[3] = 0;
+ m_core->syscon = 0;
+ m_core->sysstat = 0;
+ for (auto & elem : m_core->status_stack)
{
elem.mode1 = 0;
elem.astat = 0;
}
- m_status_stkp = 0;
- m_px = 0;
- m_opcode = 0;
- m_irq_active = 0;
- m_active_irq_num = 0;
- m_dma_status = 0;
- m_iop_delayed_reg = 0;
- m_iop_delayed_data = 0;
- m_delay_slot1 = 0;
- m_delay_slot2 = 0;
- m_systemreg_latency_cycles = 0;
- m_systemreg_latency_reg = 0;
- m_systemreg_latency_data = 0;
- m_systemreg_previous_data = 0;
- m_astat_old = 0;
- m_astat_old_old = 0;
- m_astat_old_old_old = 0;
-
- save_item(NAME(m_pc));
- save_pointer(NAME(&m_r[0].r), ARRAY_LENGTH(m_r));
- save_pointer(NAME(&m_reg_alt[0].r), ARRAY_LENGTH(m_reg_alt));
- save_item(NAME(m_mrf));
- save_item(NAME(m_mrb));
-
- save_item(NAME(m_pcstack));
- save_item(NAME(m_lcstack));
- save_item(NAME(m_lastack));
- save_item(NAME(m_lstkp));
-
- save_item(NAME(m_faddr));
- save_item(NAME(m_daddr));
- save_item(NAME(m_pcstk));
- save_item(NAME(m_pcstkp));
- save_item(NAME(m_laddr.addr));
- save_item(NAME(m_laddr.code));
- save_item(NAME(m_laddr.loop_type));
- save_item(NAME(m_curlcntr));
- save_item(NAME(m_lcntr));
-
- save_item(NAME(m_dag1.i));
- save_item(NAME(m_dag1.m));
- save_item(NAME(m_dag1.b));
- save_item(NAME(m_dag1.l));
- save_item(NAME(m_dag2.i));
- save_item(NAME(m_dag2.m));
- save_item(NAME(m_dag2.b));
- save_item(NAME(m_dag2.l));
- save_item(NAME(m_dag1_alt.i));
- save_item(NAME(m_dag1_alt.m));
- save_item(NAME(m_dag1_alt.b));
- save_item(NAME(m_dag1_alt.l));
- save_item(NAME(m_dag2_alt.i));
- save_item(NAME(m_dag2_alt.m));
- save_item(NAME(m_dag2_alt.b));
- save_item(NAME(m_dag2_alt.l));
-
- for (saveindex = 0; saveindex < ARRAY_LENGTH(m_dma); saveindex++)
- {
- save_item(NAME(m_dma[saveindex].control), saveindex);
- save_item(NAME(m_dma[saveindex].int_index), saveindex);
- save_item(NAME(m_dma[saveindex].int_modifier), saveindex);
- save_item(NAME(m_dma[saveindex].int_count), saveindex);
- save_item(NAME(m_dma[saveindex].chain_ptr), saveindex);
- save_item(NAME(m_dma[saveindex].gen_purpose), saveindex);
- save_item(NAME(m_dma[saveindex].ext_index), saveindex);
- save_item(NAME(m_dma[saveindex].ext_modifier), saveindex);
- save_item(NAME(m_dma[saveindex].ext_count), saveindex);
- }
-
- save_item(NAME(m_mode1));
- save_item(NAME(m_mode2));
- save_item(NAME(m_astat));
- save_item(NAME(m_stky));
- save_item(NAME(m_irptl));
- save_item(NAME(m_imask));
- save_item(NAME(m_imaskp));
- save_item(NAME(m_ustat1));
- save_item(NAME(m_ustat2));
-
- save_item(NAME(m_flag));
-
- save_item(NAME(m_syscon));
- save_item(NAME(m_sysstat));
-
- for (saveindex = 0; saveindex < ARRAY_LENGTH(m_status_stack); saveindex++)
- {
- save_item(NAME(m_status_stack[saveindex].mode1), saveindex);
- save_item(NAME(m_status_stack[saveindex].astat), saveindex);
- }
- save_item(NAME(m_status_stkp));
-
- save_item(NAME(m_px));
+ m_core->status_stkp = 0;
+ m_core->px = 0;
+ m_core->opcode = 0;
+ m_core->irq_pending = 0;
+ m_core->active_irq_num = 0;
+ m_core->dma_status = 0;
+ m_core->iop_delayed_reg = 0;
+ m_core->iop_delayed_data = 0;
+ m_core->delay_slot1 = 0;
+ m_core->delay_slot2 = 0;
+ m_core->systemreg_latency_cycles = 0;
+ m_core->systemreg_latency_reg = 0;
+ m_core->systemreg_latency_data = 0;
+ m_core->systemreg_previous_data = 0;
+ m_core->astat_old = 0;
+ m_core->astat_old_old = 0;
+ m_core->astat_old_old_old = 0;
+
+ m_core->fp0 = 0.0f;
+ m_core->fp1 = 1.0f;
+
+ save_item(NAME(m_core->pc));
+ save_pointer(NAME(&m_core->r[0].r), ARRAY_LENGTH(m_core->r));
+ save_pointer(NAME(&m_core->reg_alt[0].r), ARRAY_LENGTH(m_core->reg_alt));
+ save_item(NAME(m_core->mrf));
+ save_item(NAME(m_core->mrb));
+
+ save_item(NAME(m_core->pcstack));
+ save_item(NAME(m_core->lcstack));
+ save_item(NAME(m_core->lastack));
+ save_item(NAME(m_core->lstkp));
+
+ save_item(NAME(m_core->faddr));
+ save_item(NAME(m_core->daddr));
+ save_item(NAME(m_core->pcstk));
+ save_item(NAME(m_core->pcstkp));
+ save_item(NAME(m_core->laddr.addr));
+ save_item(NAME(m_core->laddr.code));
+ save_item(NAME(m_core->laddr.loop_type));
+ save_item(NAME(m_core->curlcntr));
+ save_item(NAME(m_core->lcntr));
+
+ save_item(NAME(m_core->dag1.i));
+ save_item(NAME(m_core->dag1.m));
+ save_item(NAME(m_core->dag1.b));
+ save_item(NAME(m_core->dag1.l));
+ save_item(NAME(m_core->dag2.i));
+ save_item(NAME(m_core->dag2.m));
+ save_item(NAME(m_core->dag2.b));
+ save_item(NAME(m_core->dag2.l));
+ save_item(NAME(m_core->dag1_alt.i));
+ save_item(NAME(m_core->dag1_alt.m));
+ save_item(NAME(m_core->dag1_alt.b));
+ save_item(NAME(m_core->dag1_alt.l));
+ save_item(NAME(m_core->dag2_alt.i));
+ save_item(NAME(m_core->dag2_alt.m));
+ save_item(NAME(m_core->dag2_alt.b));
+ save_item(NAME(m_core->dag2_alt.l));
+
+ for (saveindex = 0; saveindex < ARRAY_LENGTH(m_core->dma); saveindex++)
+ {
+ save_item(NAME(m_core->dma[saveindex].control), saveindex);
+ save_item(NAME(m_core->dma[saveindex].int_index), saveindex);
+ save_item(NAME(m_core->dma[saveindex].int_modifier), saveindex);
+ save_item(NAME(m_core->dma[saveindex].int_count), saveindex);
+ save_item(NAME(m_core->dma[saveindex].chain_ptr), saveindex);
+ save_item(NAME(m_core->dma[saveindex].gen_purpose), saveindex);
+ save_item(NAME(m_core->dma[saveindex].ext_index), saveindex);
+ save_item(NAME(m_core->dma[saveindex].ext_modifier), saveindex);
+ save_item(NAME(m_core->dma[saveindex].ext_count), saveindex);
+ }
+
+ save_item(NAME(m_core->mode1));
+ save_item(NAME(m_core->mode2));
+ save_item(NAME(m_core->astat));
+ save_item(NAME(m_core->stky));
+ save_item(NAME(m_core->irptl));
+ save_item(NAME(m_core->imask));
+ save_item(NAME(m_core->imaskp));
+ save_item(NAME(m_core->ustat1));
+ save_item(NAME(m_core->ustat2));
+
+ save_item(NAME(m_core->flag));
+
+ save_item(NAME(m_core->syscon));
+ save_item(NAME(m_core->sysstat));
+
+ for (saveindex = 0; saveindex < ARRAY_LENGTH(m_core->status_stack); saveindex++)
+ {
+ save_item(NAME(m_core->status_stack[saveindex].mode1), saveindex);
+ save_item(NAME(m_core->status_stack[saveindex].astat), saveindex);
+ }
+ save_item(NAME(m_core->status_stkp));
+
+ save_item(NAME(m_core->px));
save_pointer(NAME(m_internal_ram), 2 * 0x10000);
- save_item(NAME(m_opcode));
-
- save_item(NAME(m_nfaddr));
-
- save_item(NAME(m_idle));
- save_item(NAME(m_irq_active));
- save_item(NAME(m_active_irq_num));
-
- for (saveindex = 0; saveindex < ARRAY_LENGTH(m_dma_op); saveindex++)
- {
- save_item(NAME(m_dma_op[saveindex].src), saveindex);
- save_item(NAME(m_dma_op[saveindex].dst), saveindex);
- save_item(NAME(m_dma_op[saveindex].chain_ptr), saveindex);
- save_item(NAME(m_dma_op[saveindex].src_modifier), saveindex);
- save_item(NAME(m_dma_op[saveindex].dst_modifier), saveindex);
- save_item(NAME(m_dma_op[saveindex].src_count), saveindex);
- save_item(NAME(m_dma_op[saveindex].dst_count), saveindex);
- save_item(NAME(m_dma_op[saveindex].pmode), saveindex);
- save_item(NAME(m_dma_op[saveindex].chained_direction), saveindex);
- save_item(NAME(m_dma_op[saveindex].active), saveindex);
- }
-
- save_item(NAME(m_dma_status));
-
- save_item(NAME(m_interrupt_active));
-
- save_item(NAME(m_iop_delayed_reg));
- save_item(NAME(m_iop_delayed_data));
-
- save_item(NAME(m_delay_slot1));
- save_item(NAME(m_delay_slot2));
-
- save_item(NAME(m_systemreg_latency_cycles));
- save_item(NAME(m_systemreg_latency_reg));
- save_item(NAME(m_systemreg_latency_data));
- save_item(NAME(m_systemreg_previous_data));
-
- save_item(NAME(m_astat_old));
- save_item(NAME(m_astat_old_old));
- save_item(NAME(m_astat_old_old_old));
-
- state_add( SHARC_PC, "PC", m_pc).formatstr("%08X");
- state_add( SHARC_PCSTK, "PCSTK", m_pcstk).formatstr("%08X");
- state_add( SHARC_PCSTKP, "PCSTKP", m_pcstkp).formatstr("%08X");
- state_add( SHARC_LSTKP, "LSTKP", m_lstkp).formatstr("%08X");
- state_add( SHARC_FADDR, "FADDR", m_faddr).formatstr("%08X");
- state_add( SHARC_DADDR, "DADDR", m_daddr).formatstr("%08X");
- state_add( SHARC_MODE1, "MODE1", m_mode1).formatstr("%08X");
- state_add( SHARC_MODE2, "MODE2", m_mode2).formatstr("%08X");
- state_add( SHARC_ASTAT, "ASTAT", m_astat).formatstr("%08X");
- state_add( SHARC_IRPTL, "IRPTL", m_irptl).formatstr("%08X");
- state_add( SHARC_IMASK, "IMASK", m_imask).formatstr("%08X");
- state_add( SHARC_USTAT1, "USTAT1", m_ustat1).formatstr("%08X");
- state_add( SHARC_USTAT2, "USTAT2", m_ustat2).formatstr("%08X");
- state_add( SHARC_STSTKP, "STSTKP", m_status_stkp).formatstr("%08X");
-
- state_add( SHARC_R0, "R0", m_r[0].r).formatstr("%08X");
- state_add( SHARC_R1, "R1", m_r[1].r).formatstr("%08X");
- state_add( SHARC_R2, "R2", m_r[2].r).formatstr("%08X");
- state_add( SHARC_R3, "R3", m_r[3].r).formatstr("%08X");
- state_add( SHARC_R4, "R4", m_r[4].r).formatstr("%08X");
- state_add( SHARC_R5, "R5", m_r[5].r).formatstr("%08X");
- state_add( SHARC_R6, "R6", m_r[6].r).formatstr("%08X");
- state_add( SHARC_R7, "R7", m_r[7].r).formatstr("%08X");
- state_add( SHARC_R8, "R8", m_r[8].r).formatstr("%08X");
- state_add( SHARC_R9, "R9", m_r[9].r).formatstr("%08X");
- state_add( SHARC_R10, "R10", m_r[10].r).formatstr("%08X");
- state_add( SHARC_R11, "R11", m_r[11].r).formatstr("%08X");
- state_add( SHARC_R12, "R12", m_r[12].r).formatstr("%08X");
- state_add( SHARC_R13, "R13", m_r[13].r).formatstr("%08X");
- state_add( SHARC_R14, "R14", m_r[14].r).formatstr("%08X");
- state_add( SHARC_R15, "R15", m_r[15].r).formatstr("%08X");
-
- state_add( SHARC_I0, "I0", m_dag1.i[0]).formatstr("%08X");
- state_add( SHARC_I1, "I1", m_dag1.i[1]).formatstr("%08X");
- state_add( SHARC_I2, "I2", m_dag1.i[2]).formatstr("%08X");
- state_add( SHARC_I3, "I3", m_dag1.i[3]).formatstr("%08X");
- state_add( SHARC_I4, "I4", m_dag1.i[4]).formatstr("%08X");
- state_add( SHARC_I5, "I5", m_dag1.i[5]).formatstr("%08X");
- state_add( SHARC_I6, "I6", m_dag1.i[6]).formatstr("%08X");
- state_add( SHARC_I7, "I7", m_dag1.i[7]).formatstr("%08X");
- state_add( SHARC_I8, "I8", m_dag2.i[0]).formatstr("%08X");
- state_add( SHARC_I9, "I9", m_dag2.i[1]).formatstr("%08X");
- state_add( SHARC_I10, "I10", m_dag2.i[2]).formatstr("%08X");
- state_add( SHARC_I11, "I11", m_dag2.i[3]).formatstr("%08X");
- state_add( SHARC_I12, "I12", m_dag2.i[4]).formatstr("%08X");
- state_add( SHARC_I13, "I13", m_dag2.i[5]).formatstr("%08X");
- state_add( SHARC_I14, "I14", m_dag2.i[6]).formatstr("%08X");
- state_add( SHARC_I15, "I15", m_dag2.i[7]).formatstr("%08X");
-
- state_add( SHARC_M0, "M0", m_dag1.m[0]).formatstr("%08X");
- state_add( SHARC_M1, "M1", m_dag1.m[1]).formatstr("%08X");
- state_add( SHARC_M2, "M2", m_dag1.m[2]).formatstr("%08X");
- state_add( SHARC_M3, "M3", m_dag1.m[3]).formatstr("%08X");
- state_add( SHARC_M4, "M4", m_dag1.m[4]).formatstr("%08X");
- state_add( SHARC_M5, "M5", m_dag1.m[5]).formatstr("%08X");
- state_add( SHARC_M6, "M6", m_dag1.m[6]).formatstr("%08X");
- state_add( SHARC_M7, "M7", m_dag1.m[7]).formatstr("%08X");
- state_add( SHARC_M8, "M8", m_dag2.m[0]).formatstr("%08X");
- state_add( SHARC_M9, "M9", m_dag2.m[1]).formatstr("%08X");
- state_add( SHARC_M10, "M10", m_dag2.m[2]).formatstr("%08X");
- state_add( SHARC_M11, "M11", m_dag2.m[3]).formatstr("%08X");
- state_add( SHARC_M12, "M12", m_dag2.m[4]).formatstr("%08X");
- state_add( SHARC_M13, "M13", m_dag2.m[5]).formatstr("%08X");
- state_add( SHARC_M14, "M14", m_dag2.m[6]).formatstr("%08X");
- state_add( SHARC_M15, "M15", m_dag2.m[7]).formatstr("%08X");
-
- state_add( SHARC_L0, "L0", m_dag1.l[0]).formatstr("%08X");
- state_add( SHARC_L1, "L1", m_dag1.l[1]).formatstr("%08X");
- state_add( SHARC_L2, "L2", m_dag1.l[2]).formatstr("%08X");
- state_add( SHARC_L3, "L3", m_dag1.l[3]).formatstr("%08X");
- state_add( SHARC_L4, "L4", m_dag1.l[4]).formatstr("%08X");
- state_add( SHARC_L5, "L5", m_dag1.l[5]).formatstr("%08X");
- state_add( SHARC_L6, "L6", m_dag1.l[6]).formatstr("%08X");
- state_add( SHARC_L7, "L7", m_dag1.l[7]).formatstr("%08X");
- state_add( SHARC_L8, "L8", m_dag2.l[0]).formatstr("%08X");
- state_add( SHARC_L9, "L9", m_dag2.l[1]).formatstr("%08X");
- state_add( SHARC_L10, "L10", m_dag2.l[2]).formatstr("%08X");
- state_add( SHARC_L11, "L11", m_dag2.l[3]).formatstr("%08X");
- state_add( SHARC_L12, "L12", m_dag2.l[4]).formatstr("%08X");
- state_add( SHARC_L13, "L13", m_dag2.l[5]).formatstr("%08X");
- state_add( SHARC_L14, "L14", m_dag2.l[6]).formatstr("%08X");
- state_add( SHARC_L15, "L15", m_dag2.l[7]).formatstr("%08X");
-
- state_add( SHARC_B0, "B0", m_dag1.b[0]).formatstr("%08X");
- state_add( SHARC_B1, "B1", m_dag1.b[1]).formatstr("%08X");
- state_add( SHARC_B2, "B2", m_dag1.b[2]).formatstr("%08X");
- state_add( SHARC_B3, "B3", m_dag1.b[3]).formatstr("%08X");
- state_add( SHARC_B4, "B4", m_dag1.b[4]).formatstr("%08X");
- state_add( SHARC_B5, "B5", m_dag1.b[5]).formatstr("%08X");
- state_add( SHARC_B6, "B6", m_dag1.b[6]).formatstr("%08X");
- state_add( SHARC_B7, "B7", m_dag1.b[7]).formatstr("%08X");
- state_add( SHARC_B8, "B8", m_dag2.b[0]).formatstr("%08X");
- state_add( SHARC_B9, "B9", m_dag2.b[1]).formatstr("%08X");
- state_add( SHARC_B10, "B10", m_dag2.b[2]).formatstr("%08X");
- state_add( SHARC_B11, "B11", m_dag2.b[3]).formatstr("%08X");
- state_add( SHARC_B12, "B12", m_dag2.b[4]).formatstr("%08X");
- state_add( SHARC_B13, "B13", m_dag2.b[5]).formatstr("%08X");
- state_add( SHARC_B14, "B14", m_dag2.b[6]).formatstr("%08X");
- state_add( SHARC_B15, "B15", m_dag2.b[7]).formatstr("%08X");
-
- state_add( STATE_GENPC, "GENPC", m_pc).noshow();
-
- m_icountptr = &m_icount;
+ save_item(NAME(m_core->opcode));
+
+ save_item(NAME(m_core->nfaddr));
+
+ save_item(NAME(m_core->idle));
+ save_item(NAME(m_core->irq_pending));
+ save_item(NAME(m_core->active_irq_num));
+
+ for (saveindex = 0; saveindex < ARRAY_LENGTH(m_core->dma_op); saveindex++)
+ {
+ save_item(NAME(m_core->dma_op[saveindex].src), saveindex);
+ save_item(NAME(m_core->dma_op[saveindex].dst), saveindex);
+ save_item(NAME(m_core->dma_op[saveindex].chain_ptr), saveindex);
+ save_item(NAME(m_core->dma_op[saveindex].src_modifier), saveindex);
+ save_item(NAME(m_core->dma_op[saveindex].dst_modifier), saveindex);
+ save_item(NAME(m_core->dma_op[saveindex].src_count), saveindex);
+ save_item(NAME(m_core->dma_op[saveindex].dst_count), saveindex);
+ save_item(NAME(m_core->dma_op[saveindex].pmode), saveindex);
+ save_item(NAME(m_core->dma_op[saveindex].chained_direction), saveindex);
+ save_item(NAME(m_core->dma_op[saveindex].active), saveindex);
+ }
+
+ save_item(NAME(m_core->dma_status));
+
+ save_item(NAME(m_core->interrupt_active));
+
+ save_item(NAME(m_core->iop_delayed_reg));
+ save_item(NAME(m_core->iop_delayed_data));
+
+ save_item(NAME(m_core->delay_slot1));
+ save_item(NAME(m_core->delay_slot2));
+
+ save_item(NAME(m_core->systemreg_latency_cycles));
+ save_item(NAME(m_core->systemreg_latency_reg));
+ save_item(NAME(m_core->systemreg_latency_data));
+ save_item(NAME(m_core->systemreg_previous_data));
+
+ save_item(NAME(m_core->astat_old));
+ save_item(NAME(m_core->astat_old_old));
+ save_item(NAME(m_core->astat_old_old_old));
+
+ state_add( SHARC_PC, "PC", m_core->pc).formatstr("%08X");
+ state_add( SHARC_PCSTK, "PCSTK", m_core->pcstk).formatstr("%08X");
+ state_add( SHARC_PCSTKP, "PCSTKP", m_core->pcstkp).formatstr("%08X");
+ state_add( SHARC_LSTKP, "LSTKP", m_core->lstkp).formatstr("%08X");
+ state_add( SHARC_FADDR, "FADDR", m_core->faddr).formatstr("%08X");
+ state_add( SHARC_DADDR, "DADDR", m_core->daddr).formatstr("%08X");
+ state_add( SHARC_MODE1, "MODE1", m_core->mode1).formatstr("%08X");
+ state_add( SHARC_MODE2, "MODE2", m_core->mode2).formatstr("%08X");
+ state_add( SHARC_ASTAT, "ASTAT", m_core->astat).formatstr("%08X");
+ state_add( SHARC_IRPTL, "IRPTL", m_core->irptl).formatstr("%08X");
+ state_add( SHARC_IMASK, "IMASK", m_core->imask).formatstr("%08X");
+ state_add( SHARC_USTAT1, "USTAT1", m_core->ustat1).formatstr("%08X");
+ state_add( SHARC_USTAT2, "USTAT2", m_core->ustat2).formatstr("%08X");
+ state_add( SHARC_CURLCNTR, "CURLCNTR", m_core->curlcntr).formatstr("%08X");
+ state_add( SHARC_STSTKP, "STSTKP", m_core->status_stkp).formatstr("%08X");
+
+ state_add( SHARC_R0, "R0", m_core->r[0].r).formatstr("%08X");
+ state_add( SHARC_R1, "R1", m_core->r[1].r).formatstr("%08X");
+ state_add( SHARC_R2, "R2", m_core->r[2].r).formatstr("%08X");
+ state_add( SHARC_R3, "R3", m_core->r[3].r).formatstr("%08X");
+ state_add( SHARC_R4, "R4", m_core->r[4].r).formatstr("%08X");
+ state_add( SHARC_R5, "R5", m_core->r[5].r).formatstr("%08X");
+ state_add( SHARC_R6, "R6", m_core->r[6].r).formatstr("%08X");
+ state_add( SHARC_R7, "R7", m_core->r[7].r).formatstr("%08X");
+ state_add( SHARC_R8, "R8", m_core->r[8].r).formatstr("%08X");
+ state_add( SHARC_R9, "R9", m_core->r[9].r).formatstr("%08X");
+ state_add( SHARC_R10, "R10", m_core->r[10].r).formatstr("%08X");
+ state_add( SHARC_R11, "R11", m_core->r[11].r).formatstr("%08X");
+ state_add( SHARC_R12, "R12", m_core->r[12].r).formatstr("%08X");
+ state_add( SHARC_R13, "R13", m_core->r[13].r).formatstr("%08X");
+ state_add( SHARC_R14, "R14", m_core->r[14].r).formatstr("%08X");
+ state_add( SHARC_R15, "R15", m_core->r[15].r).formatstr("%08X");
+
+ state_add( SHARC_I0, "I0", m_core->dag1.i[0]).formatstr("%08X");
+ state_add( SHARC_I1, "I1", m_core->dag1.i[1]).formatstr("%08X");
+ state_add( SHARC_I2, "I2", m_core->dag1.i[2]).formatstr("%08X");
+ state_add( SHARC_I3, "I3", m_core->dag1.i[3]).formatstr("%08X");
+ state_add( SHARC_I4, "I4", m_core->dag1.i[4]).formatstr("%08X");
+ state_add( SHARC_I5, "I5", m_core->dag1.i[5]).formatstr("%08X");
+ state_add( SHARC_I6, "I6", m_core->dag1.i[6]).formatstr("%08X");
+ state_add( SHARC_I7, "I7", m_core->dag1.i[7]).formatstr("%08X");
+ state_add( SHARC_I8, "I8", m_core->dag2.i[0]).formatstr("%08X");
+ state_add( SHARC_I9, "I9", m_core->dag2.i[1]).formatstr("%08X");
+ state_add( SHARC_I10, "I10", m_core->dag2.i[2]).formatstr("%08X");
+ state_add( SHARC_I11, "I11", m_core->dag2.i[3]).formatstr("%08X");
+ state_add( SHARC_I12, "I12", m_core->dag2.i[4]).formatstr("%08X");
+ state_add( SHARC_I13, "I13", m_core->dag2.i[5]).formatstr("%08X");
+ state_add( SHARC_I14, "I14", m_core->dag2.i[6]).formatstr("%08X");
+ state_add( SHARC_I15, "I15", m_core->dag2.i[7]).formatstr("%08X");
+
+ state_add( SHARC_M0, "M0", m_core->dag1.m[0]).formatstr("%08X");
+ state_add( SHARC_M1, "M1", m_core->dag1.m[1]).formatstr("%08X");
+ state_add( SHARC_M2, "M2", m_core->dag1.m[2]).formatstr("%08X");
+ state_add( SHARC_M3, "M3", m_core->dag1.m[3]).formatstr("%08X");
+ state_add( SHARC_M4, "M4", m_core->dag1.m[4]).formatstr("%08X");
+ state_add( SHARC_M5, "M5", m_core->dag1.m[5]).formatstr("%08X");
+ state_add( SHARC_M6, "M6", m_core->dag1.m[6]).formatstr("%08X");
+ state_add( SHARC_M7, "M7", m_core->dag1.m[7]).formatstr("%08X");
+ state_add( SHARC_M8, "M8", m_core->dag2.m[0]).formatstr("%08X");
+ state_add( SHARC_M9, "M9", m_core->dag2.m[1]).formatstr("%08X");
+ state_add( SHARC_M10, "M10", m_core->dag2.m[2]).formatstr("%08X");
+ state_add( SHARC_M11, "M11", m_core->dag2.m[3]).formatstr("%08X");
+ state_add( SHARC_M12, "M12", m_core->dag2.m[4]).formatstr("%08X");
+ state_add( SHARC_M13, "M13", m_core->dag2.m[5]).formatstr("%08X");
+ state_add( SHARC_M14, "M14", m_core->dag2.m[6]).formatstr("%08X");
+ state_add( SHARC_M15, "M15", m_core->dag2.m[7]).formatstr("%08X");
+
+ state_add( SHARC_L0, "L0", m_core->dag1.l[0]).formatstr("%08X");
+ state_add( SHARC_L1, "L1", m_core->dag1.l[1]).formatstr("%08X");
+ state_add( SHARC_L2, "L2", m_core->dag1.l[2]).formatstr("%08X");
+ state_add( SHARC_L3, "L3", m_core->dag1.l[3]).formatstr("%08X");
+ state_add( SHARC_L4, "L4", m_core->dag1.l[4]).formatstr("%08X");
+ state_add( SHARC_L5, "L5", m_core->dag1.l[5]).formatstr("%08X");
+ state_add( SHARC_L6, "L6", m_core->dag1.l[6]).formatstr("%08X");
+ state_add( SHARC_L7, "L7", m_core->dag1.l[7]).formatstr("%08X");
+ state_add( SHARC_L8, "L8", m_core->dag2.l[0]).formatstr("%08X");
+ state_add( SHARC_L9, "L9", m_core->dag2.l[1]).formatstr("%08X");
+ state_add( SHARC_L10, "L10", m_core->dag2.l[2]).formatstr("%08X");
+ state_add( SHARC_L11, "L11", m_core->dag2.l[3]).formatstr("%08X");
+ state_add( SHARC_L12, "L12", m_core->dag2.l[4]).formatstr("%08X");
+ state_add( SHARC_L13, "L13", m_core->dag2.l[5]).formatstr("%08X");
+ state_add( SHARC_L14, "L14", m_core->dag2.l[6]).formatstr("%08X");
+ state_add( SHARC_L15, "L15", m_core->dag2.l[7]).formatstr("%08X");
+
+ state_add( SHARC_B0, "B0", m_core->dag1.b[0]).formatstr("%08X");
+ state_add( SHARC_B1, "B1", m_core->dag1.b[1]).formatstr("%08X");
+ state_add( SHARC_B2, "B2", m_core->dag1.b[2]).formatstr("%08X");
+ state_add( SHARC_B3, "B3", m_core->dag1.b[3]).formatstr("%08X");
+ state_add( SHARC_B4, "B4", m_core->dag1.b[4]).formatstr("%08X");
+ state_add( SHARC_B5, "B5", m_core->dag1.b[5]).formatstr("%08X");
+ state_add( SHARC_B6, "B6", m_core->dag1.b[6]).formatstr("%08X");
+ state_add( SHARC_B7, "B7", m_core->dag1.b[7]).formatstr("%08X");
+ state_add( SHARC_B8, "B8", m_core->dag2.b[0]).formatstr("%08X");
+ state_add( SHARC_B9, "B9", m_core->dag2.b[1]).formatstr("%08X");
+ state_add( SHARC_B10, "B10", m_core->dag2.b[2]).formatstr("%08X");
+ state_add( SHARC_B11, "B11", m_core->dag2.b[3]).formatstr("%08X");
+ state_add( SHARC_B12, "B12", m_core->dag2.b[4]).formatstr("%08X");
+ state_add( SHARC_B13, "B13", m_core->dag2.b[5]).formatstr("%08X");
+ state_add( SHARC_B14, "B14", m_core->dag2.b[6]).formatstr("%08X");
+ state_add( SHARC_B15, "B15", m_core->dag2.b[7]).formatstr("%08X");
+
+ state_add( STATE_GENPC, "GENPC", m_core->pc).noshow();
+
+ m_icountptr = &m_core->icount;
}
void adsp21062_device::device_reset()
@@ -645,27 +767,27 @@ void adsp21062_device::device_reset()
{
case BOOT_MODE_EPROM:
{
- m_dma[6].int_index = 0x20000;
- m_dma[6].int_modifier = 1;
- m_dma[6].int_count = 0x100;
- m_dma[6].ext_index = 0x400000;
- m_dma[6].ext_modifier = 1;
- m_dma[6].ext_count = 0x600;
- m_dma[6].control = 0x2a1;
+ m_core->dma[6].int_index = 0x20000;
+ m_core->dma[6].int_modifier = 1;
+ m_core->dma[6].int_count = 0x100;
+ m_core->dma[6].ext_index = 0x400000;
+ m_core->dma[6].ext_modifier = 1;
+ m_core->dma[6].ext_count = 0x600;
+ m_core->dma[6].control = 0x2a1;
sharc_dma_exec(6);
dma_op(6);
- m_dma_op[6].timer->adjust(attotime::never, 0);
+ m_core->dma_op[6].timer->adjust(attotime::never, 0);
break;
}
case BOOT_MODE_HOST:
{
- m_dma[6].int_index = 0x20000;
- m_dma[6].int_modifier = 1;
- m_dma[6].int_count = 0x100;
- m_dma[6].control = 0xa1;
+ m_core->dma[6].int_index = 0x20000;
+ m_core->dma[6].int_modifier = 1;
+ m_core->dma[6].int_count = 0x100;
+ m_core->dma[6].control = 0xa1;
break;
}
@@ -673,18 +795,18 @@ void adsp21062_device::device_reset()
fatalerror("SHARC: Unimplemented boot mode %d\n", m_boot_mode);
}
- m_pc = 0x20004;
- m_extdma_shift = 0;
- m_daddr = m_pc + 1;
- m_faddr = m_daddr + 1;
- m_nfaddr = m_faddr+1;
+ m_core->pc = 0x20004;
+ m_core->extdma_shift = 0;
+ m_core->daddr = m_core->pc + 1;
+ m_core->faddr = m_core->daddr + 1;
+ m_core->nfaddr = m_core->faddr+1;
- m_idle = 0;
- m_stky = 0x5400000;
+ m_core->idle = 0;
+ m_core->stky = 0x5400000;
- m_lstkp = 0;
- m_pcstkp = 0;
- m_interrupt_active = 0;
+ m_core->lstkp = 0;
+ m_core->pcstkp = 0;
+ m_core->interrupt_active = 0;
}
@@ -694,11 +816,11 @@ void adsp21062_device::execute_set_input(int irqline, int state)
{
if (state == ASSERT_LINE)
{
- m_irq_active |= 1 << (8-irqline);
+ m_core->irq_pending |= 1 << (8-irqline);
}
else
{
- m_irq_active &= ~(1 << (8-irqline));
+ m_core->irq_pending &= ~(1 << (8-irqline));
}
}
else if (irqline >= SHARC_INPUT_FLAG0 && irqline <= SHARC_INPUT_FLAG3)
@@ -712,9 +834,9 @@ void adsp21062_device::set_flag_input(int flag_num, int state)
if (flag_num >= 0 && flag_num < 4)
{
// Check if flag is set to input in MODE2 (bit == 0)
- if ((m_mode2 & (1 << (flag_num+15))) == 0)
+ if ((m_core->mode2 & (1 << (flag_num+15))) == 0)
{
- m_flag[flag_num] = state ? 1 : 0;
+ m_core->flag[flag_num] = state ? 1 : 0;
}
else
{
@@ -726,29 +848,29 @@ void adsp21062_device::set_flag_input(int flag_num, int state)
void adsp21062_device::check_interrupts()
{
int i;
- if ((m_imask & m_irq_active) && (m_mode1 & MODE1_IRPTEN) && !m_interrupt_active &&
- m_pc != m_delay_slot1 && m_pc != m_delay_slot2)
+ if ((m_core->imask & m_core->irq_pending) && (m_core->mode1 & MODE1_IRPTEN) && !m_core->interrupt_active &&
+ m_core->pc != m_core->delay_slot1 && m_core->pc != m_core->delay_slot2)
{
int which = 0;
for (i=0; i < 32; i++)
{
- if (m_irq_active & (1 << i))
+ if (m_core->irq_pending & (1 << i))
{
break;
}
which++;
}
- if (m_idle)
+ if (m_core->idle)
{
- PUSH_PC(m_pc+1);
+ PUSH_PC(m_core->pc+1);
}
else
{
- PUSH_PC(m_daddr);
+ PUSH_PC(m_core->daddr);
}
- m_irptl |= 1 << which;
+ m_core->irptl |= 1 << which;
if (which >= 6 && which <= 8)
{
@@ -759,55 +881,63 @@ void adsp21062_device::check_interrupts()
/* TODO: alter IMASKP */
- m_active_irq_num = which;
- m_irq_active &= ~(1 << which);
+ m_core->active_irq_num = which;
+ m_core->irq_pending &= ~(1 << which);
- m_interrupt_active = 1;
+ m_core->interrupt_active = 1;
}
}
void adsp21062_device::execute_run()
{
- if (m_idle && m_irq_active == 0)
+#if ENABLE_DRC
+ if (m_core->irq_pending != 0)
+ {
+ m_core->idle = 0;
+ }
+ execute_run_drc();
+ return;
+#else
+ if (m_core->idle && m_core->irq_pending == 0)
{
- m_icount = 0;
- debugger_instruction_hook(this, m_daddr);
+ m_core->icount = 0;
+ debugger_instruction_hook(this, m_core->daddr);
}
- if (m_irq_active != 0)
+ if (m_core->irq_pending != 0)
{
check_interrupts();
- m_idle = 0;
+ m_core->idle = 0;
}
- while (m_icount > 0 && !m_idle)
+ while (m_core->icount > 0 && !m_core->idle)
{
- m_pc = m_daddr;
- m_daddr = m_faddr;
- m_faddr = m_nfaddr;
- m_nfaddr++;
+ m_core->pc = m_core->daddr;
+ m_core->daddr = m_core->faddr;
+ m_core->faddr = m_core->nfaddr;
+ m_core->nfaddr++;
- m_astat_old_old_old = m_astat_old_old;
- m_astat_old_old = m_astat_old;
- m_astat_old = m_astat;
+ m_core->astat_old_old_old = m_core->astat_old_old;
+ m_core->astat_old_old = m_core->astat_old;
+ m_core->astat_old = m_core->astat;
- m_opcode = ROPCODE(m_pc);
+ debugger_instruction_hook(this, m_core->pc);
- debugger_instruction_hook(this, m_pc);
+ m_core->opcode = ROPCODE(m_core->pc);
// handle looping
- if (m_pc == m_laddr.addr)
+ if (m_core->pc == m_core->laddr.addr)
{
- switch (m_laddr.loop_type)
+ switch (m_core->laddr.loop_type)
{
case 0: // arithmetic condition-based
{
- int condition = m_laddr.code;
+ int condition = m_core->laddr.code;
{
UINT32 looptop = TOP_PC();
- if (m_pc - looptop > 2)
+ if (m_core->pc - looptop > 2)
{
- m_astat = m_astat_old_old_old;
+ m_core->astat = m_core->astat_old_old_old;
}
}
@@ -821,7 +951,7 @@ void adsp21062_device::execute_run()
CHANGE_PC(TOP_PC());
}
- m_astat = m_astat_old;
+ m_core->astat = m_core->astat_old;
break;
}
case 1: // counter-based, length 1
@@ -836,9 +966,9 @@ void adsp21062_device::execute_run()
}
case 3: // counter-based, length >2
{
- --m_lcstack[m_lstkp];
- --m_curlcntr;
- if (m_curlcntr == 0)
+ --m_core->lcstack[m_core->lstkp];
+ --m_core->curlcntr;
+ if (m_core->curlcntr == 0)
{
POP_LOOP();
POP_PC();
@@ -851,23 +981,24 @@ void adsp21062_device::execute_run()
}
}
- (this->*m_sharc_op[(m_opcode >> 39) & 0x1ff])();
+ (this->*m_sharc_op[(m_core->opcode >> 39) & 0x1ff])();
// System register latency effect
- if (m_systemreg_latency_cycles > 0)
+ if (m_core->systemreg_latency_cycles > 0)
{
- --m_systemreg_latency_cycles;
- if (m_systemreg_latency_cycles <= 0)
+ --m_core->systemreg_latency_cycles;
+ if (m_core->systemreg_latency_cycles <= 0)
{
systemreg_write_latency_effect();
}
}
- --m_icount;
+ --m_core->icount;
};
+#endif
}
bool adsp21062_device::memory_read(address_spacenum spacenum, offs_t offset, int size, UINT64 &value)
diff --git a/src/devices/cpu/sharc/sharc.h b/src/devices/cpu/sharc/sharc.h
index c658b3a9800..671076a87f7 100644
--- a/src/devices/cpu/sharc/sharc.h
+++ b/src/devices/cpu/sharc/sharc.h
@@ -5,6 +5,8 @@
#ifndef __SHARC_H__
#define __SHARC_H__
+#include "cpu/drcfe.h"
+#include "cpu/drcuml.h"
#define SHARC_INPUT_FLAG0 3
#define SHARC_INPUT_FLAG1 4
@@ -21,7 +23,7 @@ enum SHARC_BOOT_MODE
};
-struct SHARC_DAG
+struct alignas(16) SHARC_DAG
{
UINT32 i[8];
UINT32 m[8];
@@ -71,12 +73,73 @@ struct SHARC_DMA_OP
};
+// STKY flags
+#define AUS 0x1 /* ALU floating-point underflow */
+#define AVS 0x2 /* ALU floating-point overflow */
+#define AOS 0x4 /* ALU fixed-point overflow */
+#define AIS 0x20 /* ALU floating-point invalid operation */
+
+// MODE1 flags
+#define MODE1_BR8 0x1 /* Bit-reverse for I8 */
+#define MODE1_BR0 0x2 /* Bit-reverse for I0 */
+#define MODE1_SRCU 0x4 /* Alternate register select for computational units */
+#define MODE1_SRD1H 0x8 /* DAG alternate register select (7-4) */
+#define MODE1_SRD1L 0x10 /* DAG alternate register select (3-0) */
+#define MODE1_SRD2H 0x20 /* DAG alternate register select (15-12) */
+#define MODE1_SRD2L 0x40 /* DAG alternate register select (11-8) */
+#define MODE1_SRRFH 0x80 /* Register file alternate select for R(15-8) */
+#define MODE1_SRRFL 0x400 /* Register file alternate select for R(7-0) */
+#define MODE1_NESTM 0x800 /* Interrupt nesting enable */
+#define MODE1_IRPTEN 0x1000 /* Global interrupt enable */
+#define MODE1_ALUSAT 0x2000 /* Enable ALU fixed-point saturation */
+#define MODE1_SSE 0x4000 /* Enable short word sign extension */
+#define MODE1_TRUNCATE 0x8000 /* (1) Floating-point truncation / (0) round to nearest */
+#define MODE1_RND32 0x10000 /* (1) 32-bit floating-point rounding / (0) 40-bit rounding */
+#define MODE1_CSEL 0x60000 /* CSelect */
+
+// MODE2 flags
+#define MODE2_IRQ0E 0x1 /* IRQ0 (1) Edge sens. / (0) Level sens. */
+#define MODE2_IRQ1E 0x2 /* IRQ1 (1) Edge sens. / (0) Level sens. */
+#define MODE2_IRQ2E 0x4 /* IRQ2 (1) Edge sens. / (0) Level sens. */
+#define MODE2_CADIS 0x10 /* Cache disable */
+#define MODE2_TIMEN 0x20 /* Timer enable */
+#define MODE2_BUSLK 0x40 /* External bus lock */
+#define MODE2_FLG0O 0x8000 /* FLAG0 (1) Output / (0) Input */
+#define MODE2_FLG1O 0x10000 /* FLAG1 (1) Output / (0) Input */
+#define MODE2_FLG2O 0x20000 /* FLAG2 (1) Output / (0) Input */
+#define MODE2_FLG3O 0x40000 /* FLAG3 (1) Output / (0) Input */
+#define MODE2_CAFRZ 0x80000 /* Cache freeze */
+
+
+#define SIGN_EXTEND6(x) (((x) & 0x20) ? (0xffffffc0 | (x)) : (x))
+#define SIGN_EXTEND24(x) (((x) & 0x800000) ? (0xff000000 | (x)) : (x))
+#define MAKE_EXTRACT_MASK(start_bit, length) ((0xffffffff << start_bit) & (((UINT32)0xffffffff) >> (32 - (start_bit + length))))
+
+#define OP_USERFLAG_COUNTER_LOOP 0x00000001
+#define OP_USERFLAG_COND_LOOP 0x00000002
+#define OP_USERFLAG_COND_FIELD 0x0000003c
+#define OP_USERFLAG_COND_FIELD_SHIFT 2
+#define OP_USERFLAG_ASTAT_DELAY_COPY_AZ 0x00001000
+#define OP_USERFLAG_ASTAT_DELAY_COPY_AN 0x00002000
+#define OP_USERFLAG_ASTAT_DELAY_COPY_AC 0x00004000
+#define OP_USERFLAG_ASTAT_DELAY_COPY_AV 0x00008000
+#define OP_USERFLAG_ASTAT_DELAY_COPY_MV 0x00010000
+#define OP_USERFLAG_ASTAT_DELAY_COPY_MN 0x00020000
+#define OP_USERFLAG_ASTAT_DELAY_COPY_SV 0x00040000
+#define OP_USERFLAG_ASTAT_DELAY_COPY_SZ 0x00080000
+#define OP_USERFLAG_ASTAT_DELAY_COPY_BTF 0x00100000
+#define OP_USERFLAG_ASTAT_DELAY_COPY 0x001ff000
+
+
#define MCFG_SHARC_BOOT_MODE(boot_mode) \
adsp21062_device::set_boot_mode(*device, boot_mode);
+class sharc_frontend;
class adsp21062_device : public cpu_device
{
+ friend class sharc_frontend;
+
public:
// construction/destruction
adsp21062_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
@@ -91,6 +154,92 @@ public:
TIMER_CALLBACK_MEMBER(sharc_iop_delayed_write_callback);
TIMER_CALLBACK_MEMBER(sharc_dma_callback);
+ void sharc_cfunc_unimplemented();
+ void sharc_cfunc_read_iop();
+ void sharc_cfunc_write_iop();
+ void sharc_cfunc_pcstack_overflow();
+ void sharc_cfunc_pcstack_underflow();
+ void sharc_cfunc_loopstack_overflow();
+ void sharc_cfunc_loopstack_underflow();
+ void sharc_cfunc_statusstack_overflow();
+ void sharc_cfunc_statusstack_underflow();
+
+ void sharc_cfunc_unimplemented_compute();
+ void sharc_cfunc_unimplemented_shiftimm();
+ void sharc_cfunc_write_snoop();
+
+ enum ASTAT_FLAGS
+ {
+ // ASTAT flags
+ AZ = 0x1, /* ALU result zero */
+ AV = 0x2, /* ALU overflow */
+ AN = 0x4, /* ALU result negative */
+ AC = 0x8, /* ALU fixed-point carry */
+ AS = 0x10, /* ALU X input sign */
+ AI = 0x20, /* ALU floating-point invalid operation */
+ MN = 0x40, /* Multiplier result negative */
+ MV = 0x80, /* Multiplier overflow */
+ MU = 0x100, /* Multiplier underflow */
+ MI = 0x200, /* Multiplier floating-point invalid operation */
+ AF = 0x400,
+ SV = 0x800, /* Shifter overflow */
+ SZ = 0x1000, /* Shifter result zero */
+ SS = 0x2000, /* Shifter input sign */
+ BTF = 0x40000, /* Bit Test Flag */
+ FLG0 = 0x80000, /* FLAG0 */
+ FLG1 = 0x100000, /* FLAG1 */
+ FLG2 = 0x200000, /* FLAG2 */
+ FLG3 = 0x400000 /* FLAG3 */
+ };
+
+ enum ASTAT_SHIFT
+ {
+ AZ_SHIFT = 0,
+ AV_SHIFT = 1,
+ AN_SHIFT = 2,
+ AC_SHIFT = 3,
+ AS_SHIFT = 4,
+ AI_SHIFT = 5,
+ MN_SHIFT = 6,
+ MV_SHIFT = 7,
+ MU_SHIFT = 8,
+ MI_SHIFT = 9,
+ AF_SHIFT = 10,
+ SV_SHIFT = 11,
+ SZ_SHIFT = 12,
+ SS_SHIFT = 13,
+ BTF_SHIFT = 18,
+ FLG0_SHIFT = 19,
+ FLG1_SHIFT = 20,
+ FLG2_SHIFT = 21,
+ FLG3_SHIFT = 22
+ };
+
+ enum MODE1_DELAY_MODE
+ {
+ MODE1_WRITE_IMM,
+ MODE1_WRITE_REG,
+ MODE1_SET,
+ MODE1_CLEAR,
+ MODE1_TOGGLE,
+ };
+
+ enum MEM_ACCESSOR_TYPE
+ {
+ MEM_ACCESSOR_PM_READ48,
+ MEM_ACCESSOR_PM_WRITE48,
+ MEM_ACCESSOR_PM_READ32,
+ MEM_ACCESSOR_PM_WRITE32,
+ MEM_ACCESSOR_DM_READ32,
+ MEM_ACCESSOR_DM_WRITE32
+ };
+
+ enum
+ {
+ EXCEPTION_INTERRUPT = 0,
+ EXCEPTION_COUNT
+ };
+
protected:
// device-level overrides
virtual void device_start() override;
@@ -109,10 +258,12 @@ protected:
virtual bool memory_readop(offs_t offset, int size, UINT64 &value) override;
// device_disasm_interface overrides
- virtual UINT32 disasm_min_opcode_bytes() const override { return 1; }
- virtual UINT32 disasm_max_opcode_bytes() const override { return 40; }
+ virtual UINT32 disasm_min_opcode_bytes() const override { return 6; }
+ virtual UINT32 disasm_max_opcode_bytes() const override { return 6; }
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
+ direct_read_data *m_direct;
+
private:
address_space_config m_program_config;
address_space_config m_data_config;
@@ -126,94 +277,178 @@ private:
};
static const SHARC_OP s_sharc_opcode_table[];
- UINT32 m_pc;
- SHARC_REG m_r[16];
- SHARC_REG m_reg_alt[16];
- UINT64 m_mrf;
- UINT64 m_mrb;
-
- UINT32 m_pcstack[32];
- UINT32 m_lcstack[6];
- UINT32 m_lastack[6];
- UINT32 m_lstkp;
-
- UINT32 m_faddr;
- UINT32 m_daddr;
- UINT32 m_pcstk;
- UINT32 m_pcstkp;
- SHARC_LADDR m_laddr;
- UINT32 m_curlcntr;
- UINT32 m_lcntr;
- UINT8 m_extdma_shift;
-
- /* Data Address Generator (DAG) */
- SHARC_DAG m_dag1; // (DM bus)
- SHARC_DAG m_dag2; // (PM bus)
- SHARC_DAG m_dag1_alt;
- SHARC_DAG m_dag2_alt;
-
- SHARC_DMA_REGS m_dma[12];
-
- /* System registers */
- UINT32 m_mode1;
- UINT32 m_mode2;
- UINT32 m_astat;
- UINT32 m_stky;
- UINT32 m_irptl;
- UINT32 m_imask;
- UINT32 m_imaskp;
- UINT32 m_ustat1;
- UINT32 m_ustat2;
-
- UINT32 m_flag[4];
-
- UINT32 m_syscon;
- UINT32 m_sysstat;
-
- struct
+ struct ASTAT_DRC
+ {
+ union
+ {
+ struct
+ {
+ UINT32 az;
+ UINT32 av;
+ UINT32 an;
+ UINT32 ac;
+ UINT32 as;
+ UINT32 ai;
+ UINT32 mn;
+ UINT32 mv;
+ UINT32 mu;
+ UINT32 mi;
+ UINT32 sv;
+ UINT32 sz;
+ UINT32 ss;
+ UINT32 btf;
+ UINT32 af;
+ UINT32 cacc;
+ };
+ UINT64 flags64[8];
+ };
+ };
+
+ struct alignas(16) sharc_internal_state
{
+ SHARC_REG r[16];
+ SHARC_REG reg_alt[16];
+
+ UINT32 pc;
+ UINT64 mrf;
+ UINT64 mrb;
+
+ UINT32 pcstack[32];
+ UINT32 lcstack[6];
+ UINT32 lastack[6];
+ UINT32 lstkp;
+
+ UINT32 faddr;
+ UINT32 daddr;
+ UINT32 pcstk;
+ UINT32 pcstkp;
+ SHARC_LADDR laddr;
+ UINT32 curlcntr;
+ UINT32 lcntr;
+ UINT8 extdma_shift;
+
+ /* Data Address Generator (DAG) */
+ SHARC_DAG dag1; // (DM bus)
+ SHARC_DAG dag2; // (PM bus)
+ SHARC_DAG dag1_alt;
+ SHARC_DAG dag2_alt;
+
+ SHARC_DMA_REGS dma[12];
+
+ /* System registers */
UINT32 mode1;
+ UINT32 mode2;
UINT32 astat;
- } m_status_stack[5];
- INT32 m_status_stkp;
+ UINT32 stky;
+ UINT32 irptl;
+ UINT32 imask;
+ UINT32 imaskp;
+ UINT32 ustat1;
+ UINT32 ustat2;
- UINT64 m_px;
+ UINT32 flag[4];
- UINT16 *m_internal_ram_block0, *m_internal_ram_block1;
+ UINT32 syscon;
+ UINT32 sysstat;
- address_space *m_program;
- address_space *m_data;
- opcode_func m_sharc_op[512];
- int m_icount;
- UINT64 m_opcode;
+ struct
+ {
+ UINT32 mode1;
+ UINT32 astat;
+ } status_stack[5];
+ INT32 status_stkp;
- UINT32 m_nfaddr;
+ UINT64 px;
- INT32 m_idle;
- INT32 m_irq_active;
- INT32 m_active_irq_num;
+ int icount;
+ UINT64 opcode;
- SHARC_BOOT_MODE m_boot_mode;
+ UINT32 nfaddr;
+
+ INT32 idle;
+ INT32 irq_pending;
+ INT32 active_irq_num;
+
+ SHARC_DMA_OP dma_op[12];
+ UINT32 dma_status;
+
+ INT32 interrupt_active;
- SHARC_DMA_OP m_dma_op[12];
- UINT32 m_dma_status;
+ UINT32 iop_delayed_reg;
+ UINT32 iop_delayed_data;
+ emu_timer *delayed_iop_timer;
- INT32 m_interrupt_active;
+ UINT32 delay_slot1, delay_slot2;
- UINT32 m_iop_delayed_reg;
- UINT32 m_iop_delayed_data;
- emu_timer *m_delayed_iop_timer;
+ INT32 systemreg_latency_cycles;
+ INT32 systemreg_latency_reg;
+ UINT32 systemreg_latency_data;
+ UINT32 systemreg_previous_data;
- UINT32 m_delay_slot1, m_delay_slot2;
+ UINT32 astat_old;
+ UINT32 astat_old_old;
+ UINT32 astat_old_old_old;
- INT32 m_systemreg_latency_cycles;
- INT32 m_systemreg_latency_reg;
- UINT32 m_systemreg_latency_data;
- UINT32 m_systemreg_previous_data;
+ UINT32 arg0;
+ UINT32 arg1;
+ UINT32 arg2;
+ UINT32 arg3;
- UINT32 m_astat_old;
- UINT32 m_astat_old_old;
- UINT32 m_astat_old_old_old;
+ UINT64 arg64;
+ UINT32 mode1_delay_data;
+
+ ASTAT_DRC astat_drc;
+ ASTAT_DRC astat_drc_copy;
+ ASTAT_DRC astat_delay_copy;
+ UINT32 dreg_temp;
+ UINT32 jmpdest;
+
+ float fp0;
+ float fp1;
+
+ UINT32 force_recompile;
+ };
+
+ sharc_internal_state* m_core;
+
+ SHARC_BOOT_MODE m_boot_mode;
+
+ // UML stuff
+ drc_cache m_cache;
+ std::unique_ptr<drcuml_state> m_drcuml;
+ std::unique_ptr<sharc_frontend> m_drcfe;
+ uml::parameter m_regmap[16];
+
+ uml::code_handle *m_entry; /* entry point */
+ uml::code_handle *m_nocode; /* nocode exception handler */
+ uml::code_handle *m_out_of_cycles; /* out of cycles exception handler */
+ uml::code_handle *m_pm_read48;
+ uml::code_handle *m_pm_write48;
+ uml::code_handle *m_pm_read32;
+ uml::code_handle *m_pm_write32;
+ uml::code_handle *m_dm_read32;
+ uml::code_handle *m_dm_write32;
+ uml::code_handle *m_push_pc;
+ uml::code_handle *m_pop_pc;
+ uml::code_handle *m_push_loop;
+ uml::code_handle *m_pop_loop;
+ uml::code_handle *m_push_status;
+ uml::code_handle *m_pop_status;
+ uml::code_handle *m_exception[EXCEPTION_COUNT]; // exception handlers
+ uml::code_handle *m_swap_dag1_0_3;
+ uml::code_handle *m_swap_dag1_4_7;
+ uml::code_handle *m_swap_dag2_0_3;
+ uml::code_handle *m_swap_dag2_4_7;
+ uml::code_handle *m_swap_r0_7;
+ uml::code_handle *m_swap_r8_15;
+
+ bool m_cache_dirty;
+
+ UINT16 *m_internal_ram_block0, *m_internal_ram_block1;
+
+ address_space *m_program;
+ address_space *m_data;
+ opcode_func m_sharc_op[512];
UINT16 m_internal_ram[2 * 0x10000]; // 2x 128KB
@@ -349,6 +584,59 @@ private:
inline void compute_fmul_dual_fadd_fsub(int fm, int fxm, int fym, int fa, int fs, int fxa, int fya);
void build_opcode_table();
+ /* internal compiler state */
+ struct compiler_state
+ {
+ UINT32 cycles; /* accumulated cycles */
+ UINT8 checkints; /* need to check interrupts before next instruction */
+ uml::code_label labelnum; /* index for local labels */
+ struct
+ {
+ int counter;
+ int mode;
+ UINT32 data;
+ } mode1_delay;
+ };
+
+ void execute_run_drc();
+ void flush_cache();
+ void compile_block(offs_t pc);
+ void alloc_handle(drcuml_state *drcuml, uml::code_handle **handleptr, const char *name);
+ void static_generate_entry_point();
+ void static_generate_nocode_handler();
+ void static_generate_out_of_cycles();
+ void static_generate_memory_accessor(MEM_ACCESSOR_TYPE type, const char *name, uml::code_handle *&handleptr);
+ void static_generate_exception(UINT8 exception, const char *name);
+ void static_generate_push_pc();
+ void static_generate_pop_pc();
+ void static_generate_push_loop();
+ void static_generate_pop_loop();
+ void static_generate_push_status();
+ void static_generate_pop_status();
+ void static_generate_mode1_ops();
+ void load_fast_iregs(drcuml_block *block);
+ void save_fast_iregs(drcuml_block *block);
+ void generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, int allow_exception);
+ int generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_unimplemented_compute(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_compute(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
+ void generate_if_condition(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int condition, int skip_label);
+ void generate_do_condition(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int condition, int skip_label, ASTAT_DRC &astat);
+ void generate_shift_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int data, int shiftop, int rn, int rx);
+ void generate_call(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, bool delayslot);
+ void generate_jump(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, bool delayslot, bool loopabort, bool clearint);
+ void generate_write_mode1_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 data);
+ void generate_set_mode1_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 data);
+ void generate_clear_mode1_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 data);
+ void generate_toggle_mode1_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 data);
+ void generate_read_ureg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int ureg, bool has_compute);
+ void generate_write_ureg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int ureg, bool imm, UINT32 data);
+ void generate_update_circular_buffer(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int g, int i);
+ void generate_astat_copy(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
+
+ bool if_condition_always_true(int condition);
+ UINT32 do_condition_astat_bits(int condition);
};
diff --git a/src/devices/cpu/sharc/sharcdma.hxx b/src/devices/cpu/sharc/sharcdma.hxx
index eacede6fb5b..9321dd88b05 100644
--- a/src/devices/cpu/sharc/sharcdma.hxx
+++ b/src/devices/cpu/sharc/sharcdma.hxx
@@ -21,80 +21,80 @@ void adsp21062_device::schedule_chained_dma_op(int channel, UINT32 dma_chain_ptr
UINT32 ext_modifier = dm_read32(op_ptr - 6);
UINT32 ext_count = dm_read32(op_ptr - 7);
- if (m_dma_op[channel].active)
+ if (m_core->dma_op[channel].active)
{
- fatalerror("schedule_chained_dma_op: DMA operation already scheduled at %08X!\n", m_pc);
+ fatalerror("schedule_chained_dma_op: DMA operation already scheduled at %08X!\n", m_core->pc);
}
if (chained_direction) // Transmit to external
{
- m_dma_op[channel].dst = ext_index;
- m_dma_op[channel].dst_modifier = ext_modifier;
- m_dma_op[channel].dst_count = ext_count;
- m_dma_op[channel].src = int_index;
- m_dma_op[channel].src_modifier = int_modifier;
- m_dma_op[channel].src_count = int_count;
+ m_core->dma_op[channel].dst = ext_index;
+ m_core->dma_op[channel].dst_modifier = ext_modifier;
+ m_core->dma_op[channel].dst_count = ext_count;
+ m_core->dma_op[channel].src = int_index;
+ m_core->dma_op[channel].src_modifier = int_modifier;
+ m_core->dma_op[channel].src_count = int_count;
}
else // Receive from external
{
- m_dma_op[channel].src = ext_index;
- m_dma_op[channel].src_modifier = ext_modifier;
- m_dma_op[channel].src_count = ext_count;
- m_dma_op[channel].dst = int_index;
- m_dma_op[channel].dst_modifier = int_modifier;
- m_dma_op[channel].dst_count = int_count;
+ m_core->dma_op[channel].src = ext_index;
+ m_core->dma_op[channel].src_modifier = ext_modifier;
+ m_core->dma_op[channel].src_count = ext_count;
+ m_core->dma_op[channel].dst = int_index;
+ m_core->dma_op[channel].dst_modifier = int_modifier;
+ m_core->dma_op[channel].dst_count = int_count;
}
- m_dma_op[channel].pmode = 0;
- m_dma_op[channel].chain_ptr = chain_ptr;
- m_dma_op[channel].chained_direction = chained_direction;
+ m_core->dma_op[channel].pmode = 0;
+ m_core->dma_op[channel].chain_ptr = chain_ptr;
+ m_core->dma_op[channel].chained_direction = chained_direction;
- m_dma_op[channel].active = true;
+ m_core->dma_op[channel].active = true;
- int cycles = m_dma_op[channel].src_count / 4;
- m_dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel);
+ int cycles = m_core->dma_op[channel].src_count / 4;
+ m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel);
// enable busy flag
- m_dma_status |= (1 << channel);
+ m_core->dma_status |= (1 << channel);
}
void adsp21062_device::schedule_dma_op(int channel, UINT32 src, UINT32 dst, int src_modifier, int dst_modifier, int src_count, int dst_count, int pmode)
{
- if (m_dma_op[channel].active)
+ if (m_core->dma_op[channel].active)
{
- fatalerror("schedule_dma_op: DMA operation already scheduled at %08X!\n", m_pc);
+ fatalerror("schedule_dma_op: DMA operation already scheduled at %08X!\n", m_core->pc);
}
- m_dma_op[channel].src = src;
- m_dma_op[channel].dst = dst;
- m_dma_op[channel].src_modifier = src_modifier;
- m_dma_op[channel].dst_modifier = dst_modifier;
- m_dma_op[channel].src_count = src_count;
- m_dma_op[channel].dst_count = dst_count;
- m_dma_op[channel].pmode = pmode;
- m_dma_op[channel].chain_ptr = 0;
+ m_core->dma_op[channel].src = src;
+ m_core->dma_op[channel].dst = dst;
+ m_core->dma_op[channel].src_modifier = src_modifier;
+ m_core->dma_op[channel].dst_modifier = dst_modifier;
+ m_core->dma_op[channel].src_count = src_count;
+ m_core->dma_op[channel].dst_count = dst_count;
+ m_core->dma_op[channel].pmode = pmode;
+ m_core->dma_op[channel].chain_ptr = 0;
- m_dma_op[channel].active = true;
+ m_core->dma_op[channel].active = true;
int cycles = src_count / 4;
- m_dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel);
+ m_core->dma_op[channel].timer->adjust(cycles_to_attotime(cycles), channel);
// enable busy flag
- m_dma_status |= (1 << channel);
+ m_core->dma_status |= (1 << channel);
}
void adsp21062_device::dma_op(int channel)
{
int i;
- UINT32 src = m_dma_op[channel].src;
- UINT32 dst = m_dma_op[channel].dst;
- int src_modifier = m_dma_op[channel].src_modifier;
- int dst_modifier = m_dma_op[channel].dst_modifier;
- int src_count = m_dma_op[channel].src_count;
- //int dst_count = m_dma_op[channel].dst_count;
- int pmode = m_dma_op[channel].pmode;
+ UINT32 src = m_core->dma_op[channel].src;
+ UINT32 dst = m_core->dma_op[channel].dst;
+ int src_modifier = m_core->dma_op[channel].src_modifier;
+ int dst_modifier = m_core->dma_op[channel].dst_modifier;
+ int src_count = m_core->dma_op[channel].src_count;
+ //int dst_count = m_core->dma_op[channel].dst_count;
+ int pmode = m_core->dma_op[channel].pmode;
- //printf("dma_op: %08X, %08X, %08X, %08X, %08X, %08X, %d\n", src, dst, src_modifier, dst_modifier, src_count, dst_count, pmode);
+ //printf("dma_op: %08X, %08X, %08X, %08X, %08X, %d\n", src, dst, src_modifier, dst_modifier, src_count, pmode);
switch (pmode)
{
@@ -148,19 +148,19 @@ void adsp21062_device::dma_op(int channel)
if (channel == 6)
{
- m_irptl |= (1 << (channel+10));
+ m_core->irptl |= (1 << (channel+10));
/* DMA interrupt */
- if (m_imask & (1 << (channel+10)))
+ if (m_core->imask & (1 << (channel+10)))
{
- m_irq_active |= 1 << (channel+10);
+ m_core->irq_pending |= 1 << (channel+10);
}
}
// clear busy flag
- m_dma_status &= ~(1 << channel);
+ m_core->dma_status &= ~(1 << channel);
- m_dma_op[channel].active = false;
+ m_core->dma_op[channel].active = false;
}
void adsp21062_device::sharc_dma_exec(int channel)
@@ -170,16 +170,16 @@ void adsp21062_device::sharc_dma_exec(int channel)
UINT32 src_modifier, dst_modifier;
int chen, tran, dtype, pmode, /*mswf, master,*/ ishake, intio/*, ext, flsh*/;
- chen = (m_dma[channel].control >> 1) & 0x1;
- tran = (m_dma[channel].control >> 2) & 0x1;
- dtype = (m_dma[channel].control >> 5) & 0x1;
- pmode = (m_dma[channel].control >> 6) & 0x3;
- //mswf = (m_dma[channel].control >> 8) & 0x1;
- //master = (m_dma[channel].control >> 9) & 0x1;
- ishake = (m_dma[channel].control >> 10) & 0x1;
- intio = (m_dma[channel].control >> 11) & 0x1;
- //ext = (m_dma[channel].control >> 12) & 0x1;
- //flsh = (m_dma[channel].control >> 13) & 0x1;
+ chen = (m_core->dma[channel].control >> 1) & 0x1;
+ tran = (m_core->dma[channel].control >> 2) & 0x1;
+ dtype = (m_core->dma[channel].control >> 5) & 0x1;
+ pmode = (m_core->dma[channel].control >> 6) & 0x3;
+ //mswf = (m_core->dma[channel].control >> 8) & 0x1;
+ //master = (m_core->dma[channel].control >> 9) & 0x1;
+ ishake = (m_core->dma[channel].control >> 10) & 0x1;
+ intio = (m_core->dma[channel].control >> 11) & 0x1;
+ //ext = (m_core->dma[channel].control >> 12) & 0x1;
+ //flsh = (m_core->dma[channel].control >> 13) & 0x1;
if (ishake)
fatalerror("SHARC: dma_exec: handshake not supported\n");
@@ -189,7 +189,7 @@ void adsp21062_device::sharc_dma_exec(int channel)
if (chen) // Chained DMA
{
- UINT32 dma_chain_ptr = m_dma[channel].chain_ptr & 0x1ffff;
+ UINT32 dma_chain_ptr = m_core->dma[channel].chain_ptr & 0x1ffff;
schedule_chained_dma_op(channel, dma_chain_ptr, tran);
}
@@ -197,21 +197,21 @@ void adsp21062_device::sharc_dma_exec(int channel)
{
if (tran) // Transmit to external
{
- dst = m_dma[channel].ext_index;
- dst_modifier = m_dma[channel].ext_modifier;
- dst_count = m_dma[channel].ext_count;
- src = (m_dma[channel].int_index & 0x1ffff) | 0x20000;
- src_modifier = m_dma[channel].int_modifier;
- src_count = m_dma[channel].int_count;
+ dst = m_core->dma[channel].ext_index;
+ dst_modifier = m_core->dma[channel].ext_modifier;
+ dst_count = m_core->dma[channel].ext_count;
+ src = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000;
+ src_modifier = m_core->dma[channel].int_modifier;
+ src_count = m_core->dma[channel].int_count;
}
else // Receive from external
{
- src = m_dma[channel].ext_index;
- src_modifier = m_dma[channel].ext_modifier;
- src_count = m_dma[channel].ext_count;
- dst = (m_dma[channel].int_index & 0x1ffff) | 0x20000;
- dst_modifier = m_dma[channel].int_modifier;
- dst_count = m_dma[channel].int_count;
+ src = m_core->dma[channel].ext_index;
+ src_modifier = m_core->dma[channel].ext_modifier;
+ src_count = m_core->dma[channel].ext_count;
+ dst = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000;
+ dst_modifier = m_core->dma[channel].int_modifier;
+ dst_count = m_core->dma[channel].int_count;
}
if (dtype)
@@ -228,19 +228,19 @@ TIMER_CALLBACK_MEMBER(adsp21062_device::sharc_dma_callback)
{
int channel = param;
- m_dma_op[channel].timer->adjust(attotime::never, 0);
+ m_core->dma_op[channel].timer->adjust(attotime::never, 0);
- m_irptl |= (1 << (channel+10));
+ m_core->irptl |= (1 << (channel+10));
// DMA interrupt
- if (m_imask & (1 << (channel+10)))
+ if (m_core->imask & (1 << (channel+10)))
{
- m_irq_active |= 1 << (channel+10);
+ m_core->irq_pending |= 1 << (channel+10);
}
dma_op(channel);
- if (m_dma_op[channel].chain_ptr != 0)
+ if (m_core->dma_op[channel].chain_ptr != 0)
{
- schedule_chained_dma_op(channel, m_dma_op[channel].chain_ptr, m_dma_op[channel].chained_direction);
+ schedule_chained_dma_op(channel, m_core->dma_op[channel].chain_ptr, m_core->dma_op[channel].chained_direction);
}
}
diff --git a/src/devices/cpu/sharc/sharcdrc.cpp b/src/devices/cpu/sharc/sharcdrc.cpp
new file mode 100644
index 00000000000..2f7f3e0fbcb
--- /dev/null
+++ b/src/devices/cpu/sharc/sharcdrc.cpp
@@ -0,0 +1,4909 @@
+// license:BSD-3-Clause
+// copyright-holders:Ville Linde
+
+/******************************************************************************
+
+ SHARC UML recompiler core
+
+******************************************************************************/
+
+#include "emu.h"
+#include "debugger.h"
+#include "sharc.h"
+#include "sharcfe.h"
+#include "cpu/drcfe.h"
+#include "cpu/drcuml.h"
+#include "cpu/drcumlsh.h"
+
+using namespace uml;
+
+#define USE_SWAPDQ 0
+#define WRITE_SNOOP 0
+
+
+// map variables
+#define MAPVAR_PC M0
+#define MAPVAR_CYCLES M1
+
+// exit codes
+#define EXECUTE_OUT_OF_CYCLES 0
+#define EXECUTE_MISSING_CODE 1
+#define EXECUTE_UNMAPPED_CODE 2
+#define EXECUTE_RESET_CACHE 3
+
+
+#define REG(reg) m_regmap[reg]
+#define DM_I(reg) mem(&m_core->dag1.i[reg])
+#define DM_M(reg) mem(&m_core->dag1.m[reg])
+#define DM_L(reg) mem(&m_core->dag1.l[reg])
+#define DM_B(reg) mem(&m_core->dag1.b[reg])
+#define PM_I(reg) mem(&m_core->dag2.i[reg])
+#define PM_M(reg) mem(&m_core->dag2.m[reg])
+#define PM_L(reg) mem(&m_core->dag2.l[reg])
+#define PM_B(reg) mem(&m_core->dag2.b[reg])
+#define ASTAT_AZ mem(&m_core->astat_drc.az)
+#define ASTAT_AV mem(&m_core->astat_drc.av)
+#define ASTAT_AN mem(&m_core->astat_drc.an)
+#define ASTAT_AC mem(&m_core->astat_drc.ac)
+#define ASTAT_AS mem(&m_core->astat_drc.as)
+#define ASTAT_AI mem(&m_core->astat_drc.ai)
+#define ASTAT_AF mem(&m_core->astat_drc.af)
+#define ASTAT_MN mem(&m_core->astat_drc.mn)
+#define ASTAT_MV mem(&m_core->astat_drc.mv)
+#define ASTAT_MU mem(&m_core->astat_drc.mu)
+#define ASTAT_MI mem(&m_core->astat_drc.mi)
+#define ASTAT_SV mem(&m_core->astat_drc.sv)
+#define ASTAT_SZ mem(&m_core->astat_drc.sz)
+#define ASTAT_SS mem(&m_core->astat_drc.ss)
+#define ASTAT_BTF mem(&m_core->astat_drc.btf)
+#define FLAG0 mem(&m_core->flag[0])
+#define FLAG1 mem(&m_core->flag[1])
+#define FLAG2 mem(&m_core->flag[2])
+#define FLAG3 mem(&m_core->flag[3])
+#define CURLCNTR mem(&m_core->curlcntr)
+#define LCNTR mem(&m_core->lcntr)
+#define PCSTK mem(&m_core->pcstk)
+#define PCSTKP mem(&m_core->pcstkp)
+#define STKY mem(&m_core->stky)
+#define LSTKP mem(&m_core->lstkp)
+#define USTAT1 mem(&m_core->ustat1)
+#define USTAT2 mem(&m_core->ustat2)
+#define IRPTL mem(&m_core->irptl)
+#define MODE1 mem(&m_core->mode1)
+#define MODE2 mem(&m_core->mode2)
+#define IMASK mem(&m_core->imask)
+#define IMASKP mem(&m_core->imaskp)
+#define MRF mem(&m_core->mrf)
+#define MRB mem(&m_core->mrb)
+
+#define AZ_CALC_REQUIRED ((desc->regreq[0] & 0x00010000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define AV_CALC_REQUIRED ((desc->regreq[0] & 0x00020000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define AN_CALC_REQUIRED ((desc->regreq[0] & 0x00040000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define AC_CALC_REQUIRED ((desc->regreq[0] & 0x00080000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define AS_CALC_REQUIRED ((desc->regreq[0] & 0x00100000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define AI_CALC_REQUIRED ((desc->regreq[0] & 0x00200000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define MN_CALC_REQUIRED ((desc->regreq[0] & 0x00400000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define MV_CALC_REQUIRED ((desc->regreq[0] & 0x00800000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define MU_CALC_REQUIRED ((desc->regreq[0] & 0x01000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define MI_CALC_REQUIRED ((desc->regreq[0] & 0x02000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define SV_CALC_REQUIRED ((desc->regreq[0] & 0x04000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define SZ_CALC_REQUIRED ((desc->regreq[0] & 0x08000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define SS_CALC_REQUIRED ((desc->regreq[0] & 0x10000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define BTF_CALC_REQUIRED ((desc->regreq[0] & 0x20000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define AF_CALC_REQUIRED ((desc->regreq[0] & 0x40000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+
+
+#define IRAM_BLOCK0_START 0x20000
+#define IRAM_BLOCK0_END 0x27fff
+#define IRAM_BLOCK1_START 0x28000
+#define IRAM_BLOCK1_END 0x3ffff
+#define IRAM_SHORT_BLOCK0_START 0x40000
+#define IRAM_SHORT_BLOCK0_END 0x4ffff
+#define IRAM_SHORT_BLOCK1_START 0x50000
+#define IRAM_SHORT_BLOCK1_END 0x7ffff
+#define IOP_REGISTER_START 0x00000
+#define IOP_REGISTER_END 0x000ff
+#define IRAM_END 0x7ffff
+
+
+inline void adsp21062_device::alloc_handle(drcuml_state *drcuml, code_handle **handleptr, const char *name)
+{
+ if (*handleptr == nullptr)
+ *handleptr = drcuml->handle_alloc(name);
+}
+
+
+
+static void cfunc_unimplemented(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_unimplemented();
+}
+
+static void cfunc_read_iop(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_read_iop();
+}
+
+static void cfunc_write_iop(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_write_iop();
+}
+
+static void cfunc_pcstack_overflow(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_pcstack_overflow();
+}
+
+static void cfunc_pcstack_underflow(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_pcstack_underflow();
+}
+
+static void cfunc_loopstack_overflow(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_loopstack_overflow();
+}
+
+static void cfunc_loopstack_underflow(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_loopstack_underflow();
+}
+
+static void cfunc_statusstack_overflow(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_statusstack_overflow();
+}
+
+static void cfunc_statusstack_underflow(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_statusstack_underflow();
+}
+
+static void cfunc_unimplemented_compute(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_unimplemented_compute();
+}
+
+static void cfunc_unimplemented_shiftimm(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_unimplemented_shiftimm();
+}
+
+
+#if WRITE_SNOOP
+void adsp21062_device::sharc_cfunc_write_snoop()
+{
+ printf("Write %08X to %08X at %08X\n", m_core->arg0, m_core->arg1, m_core->arg2);
+}
+
+static void cfunc_write_snoop(void *param)
+{
+ adsp21062_device *sharc = (adsp21062_device *)param;
+ sharc->sharc_cfunc_write_snoop();
+}
+#endif
+
+
+void adsp21062_device::sharc_cfunc_unimplemented()
+{
+ UINT64 op = m_core->arg64;
+ fatalerror("PC=%08X: Unimplemented op %04X%08X\n", m_core->pc, (UINT32)(op >> 32), (UINT32)(op));
+}
+
+void adsp21062_device::sharc_cfunc_unimplemented_compute()
+{
+ UINT64 op = m_core->arg64;
+ fatalerror("PC=%08X: Unimplemented compute %04X%08X\n", m_core->pc, (UINT32)(op >> 32), (UINT32)(op));
+}
+
+void adsp21062_device::sharc_cfunc_unimplemented_shiftimm()
+{
+ UINT64 op = m_core->arg64;
+ fatalerror("PC=%08X: Unimplemented shiftimm %04X%08X\n", m_core->pc, (UINT32)(op >> 32), (UINT32)(op));
+}
+
+void adsp21062_device::sharc_cfunc_read_iop()
+{
+ m_core->arg1 = sharc_iop_r(m_core->arg0);
+}
+
+void adsp21062_device::sharc_cfunc_write_iop()
+{
+ sharc_iop_w(m_core->arg0, m_core->arg1);
+}
+
+void adsp21062_device::sharc_cfunc_pcstack_overflow()
+{
+ fatalerror("SHARC: PCStack overflow");
+}
+
+void adsp21062_device::sharc_cfunc_pcstack_underflow()
+{
+ fatalerror("SHARC: PCStack underflow");
+}
+
+void adsp21062_device::sharc_cfunc_loopstack_overflow()
+{
+ fatalerror("SHARC: Loop Stack overflow");
+}
+
+void adsp21062_device::sharc_cfunc_loopstack_underflow()
+{
+ fatalerror("SHARC: Loop Stack underflow");
+}
+
+void adsp21062_device::sharc_cfunc_statusstack_overflow()
+{
+ fatalerror("SHARC: Status Stack overflow");
+}
+
+void adsp21062_device::sharc_cfunc_statusstack_underflow()
+{
+ fatalerror("SHARC: Status Stack underflow");
+}
+
+
+bool adsp21062_device::if_condition_always_true(int condition)
+{
+ if (condition == 0x1f || condition == 0x1e)
+ return true;
+ else
+ return false;
+}
+
+UINT32 adsp21062_device::do_condition_astat_bits(int condition)
+{
+ UINT32 r = 0;
+ switch (condition)
+ {
+ case 0x00: r = AZ; break; // EQ
+ case 0x01: r = AZ | AN; break; // LT
+ case 0x02: r = AZ | AN; break; // LE
+ case 0x03: r = AC; break; // AC
+ case 0x04: r = AV; break; // AV
+ case 0x05: r = MV; break; // MV
+ case 0x06: r = MN; break; // MS
+ case 0x07: r = SV; break; // SV
+ case 0x08: r = SZ; break; // SZ
+ case 0x0d: r = BTF; break; // TF
+ case 0x10: r = AZ; break; // NOT EQUAL
+ case 0x11: r = AZ | AN; break; // GE
+ case 0x12: r = AZ | AN; break; // GT
+ case 0x13: r = AC; break; // NOT AC
+ case 0x14: r = AV; break; // NOT AV
+ case 0x15: r = MV; break; // NOT MV
+ case 0x16: r = MN; break; // NOT MS
+ case 0x17: r = SV; break; // NOT SV
+ case 0x18: r = SZ; break; // NOT SZ
+ case 0x1d: r = BTF; break; // NOT TF
+ }
+
+ return r;
+}
+
+
+/*-------------------------------------------------
+load_fast_iregs - load any fast integer
+registers
+-------------------------------------------------*/
+
+inline void adsp21062_device::load_fast_iregs(drcuml_block *block)
+{
+ int regnum;
+
+ for (regnum = 0; regnum < ARRAY_LENGTH(m_regmap); regnum++)
+ {
+ if (m_regmap[regnum].is_int_register())
+ {
+ UML_MOV(block, ireg(m_regmap[regnum].ireg() - REG_I0), mem(&m_core->r[regnum]));
+ }
+ }
+}
+
+
+/*-------------------------------------------------
+save_fast_iregs - save any fast integer
+registers
+-------------------------------------------------*/
+
+void adsp21062_device::save_fast_iregs(drcuml_block *block)
+{
+ int regnum;
+
+ for (regnum = 0; regnum < ARRAY_LENGTH(m_regmap); regnum++)
+ {
+ if (m_regmap[regnum].is_int_register())
+ {
+ UML_MOV(block, mem(&m_core->r[regnum]), ireg(m_regmap[regnum].ireg() - REG_I0));
+ }
+ }
+}
+
+void adsp21062_device::static_generate_memory_accessor(MEM_ACCESSOR_TYPE type, const char *name, code_handle *&handleptr)
+{
+ // I0 = read/write data
+ // I1 = address
+ // I2 is trashed
+
+ void* block0 = &m_internal_ram_block0[0];
+ void* block0_1 = &m_internal_ram_block0[1];
+ void* block0_2 = &m_internal_ram_block0[2];
+ void* block1 = &m_internal_ram_block1[0];
+ void* block1_1 = &m_internal_ram_block1[1];
+ void* block1_2 = &m_internal_ram_block1[2];
+
+ code_label label = 1;
+
+ drcuml_block *block = m_drcuml->begin_block(1024);
+
+ // add a global entry for this
+ alloc_handle(m_drcuml.get(), &handleptr, name);
+ UML_HANDLE(block, *handleptr); // handle *handleptr
+
+ switch (type)
+ {
+ case MEM_ACCESSOR_PM_READ48:
+ UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
+ UML_JMPc(block, COND_B, label); // jb label1
+ UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
+ UML_JMPc(block, COND_A, label); // ja label1
+
+ // 0x20000 ... 0x27fff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
+ UML_MULS(block, I1, I1, I1, 3); // muls i1,3
+ UML_DLOAD(block, I0, block0, I1, SIZE_WORD, SCALE_x2); // dload i0,[block0],i1,word,scale_x2
+ UML_DSHL(block, I0, I0, 32); // dshl i0,i0,32
+ UML_DLOAD(block, I2, block0_1, I1, SIZE_WORD, SCALE_x2); // dload i2,[block0_1],i1,word,scale_x2
+ UML_DSHL(block, I2, I2, 16); // dshl i2,i2,16
+ UML_DOR(block, I0, I0, I2); // dor i0,i0,i2
+ UML_DLOAD(block, I2, block0_2, I1, SIZE_WORD, SCALE_x2); // dload i2,[block0_2],i1,word,scale_x2
+ UML_DOR(block, I0, I0, I2); // dor i0,i0,i2
+ UML_RET(block); // ret
+
+ UML_LABEL(block, label++); // label1:
+ UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
+ UML_JMPc(block, COND_B, label); // jb label2
+ UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
+ UML_JMPc(block, COND_A, label); // ja label2
+
+ // 0x28000 ... 0x3ffff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff (block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff)
+ UML_MULS(block, I1, I1, I1, 3); // muls i1,3
+ UML_DLOAD(block, I0, block1, I1, SIZE_WORD, SCALE_x2); // dload i0,[block1],i1,word,scale_x2
+ UML_DSHL(block, I0, I0, 32); // dshl i0,i0,32
+ UML_DLOAD(block, I2, block1_1, I1, SIZE_WORD, SCALE_x2); // dload i2,[block1_1],i1,word,scale_x2
+ UML_DSHL(block, I2, I2, 16); // dshl i2,i2,16
+ UML_DOR(block, I0, I0, I2); // dor i0,i0,i2
+ UML_DLOAD(block, I2, block1_2, I1, SIZE_WORD, SCALE_x2); // dload i2,[block1_2],i1,word,scale_x2
+ UML_DOR(block, I0, I0, I2); // dor i0,i0,i2
+ UML_RET(block); // ret
+
+ UML_LABEL(block, label++); // label2:
+ break;
+
+ case MEM_ACCESSOR_PM_WRITE48:
+ UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
+ UML_JMPc(block, COND_B, label); // jb label1
+ UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
+ UML_JMPc(block, COND_A, label); // ja label1
+
+ // 0x20000 ... 0x27fff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
+ UML_MULS(block, I1, I1, I1, 3); // muls i1,3
+ UML_DSTORE(block, block0_2, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block0_2],i1,i0,word,scale_x2
+ UML_DSHR(block, I0, I0, 16); // dshr i0,i0,16
+ UML_DSTORE(block, block0_1, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block0_1],i1,i0,word,scale_x2
+ UML_DSHR(block, I0, I0, 16); // dshr i0,i0,16
+ UML_DSTORE(block, block0, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block0],i1,i0,word,scale_x2
+ UML_MOV(block, mem(&m_core->force_recompile), 1);
+ UML_RET(block); // ret
+
+ UML_LABEL(block, label++); // label1:
+ UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
+ UML_JMPc(block, COND_B, label); // jb label2
+ UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
+ UML_JMPc(block, COND_A, label); // ja label2
+
+ // 0x28000 ... 0x3ffff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff (block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff)
+ UML_MULS(block, I1, I1, I1, 3); // muls i1,3
+ UML_DSTORE(block, block1_2, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block1_2],i1,i0,word,scale_x2
+ UML_DSHR(block, I0, I0, 16); // dshr i0,i0,16
+ UML_DSTORE(block, block1_1, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block1_1],i1,i0,word,scale_x2
+ UML_DSHR(block, I0, I0, 16); // dshr i0,i0,16
+ UML_DSTORE(block, block1, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block1],i1,i0,word,scale_x2
+ UML_RET(block); // ret
+
+ UML_LABEL(block, label++); // label2:
+ break;
+
+ case MEM_ACCESSOR_PM_READ32:
+ UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
+ UML_JMPc(block, COND_B, label); // jb label1
+ UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
+ UML_JMPc(block, COND_A, label); // ja label1
+
+ // 0x20000 ... 0x27fff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
+ UML_MULS(block, I1, I1, I1, 3); // muls i1,3
+ UML_LOAD(block, I0, block0, I1, SIZE_WORD, SCALE_x2); // load i0,[block0],i1,word,scale_x2
+ UML_SHL(block, I0, I0, 16); // shl i0,i0,16
+ UML_LOAD(block, I2, block0_1, I1, SIZE_WORD, SCALE_x2); // load i2,[block0_1],i1,word,scale_x2
+ UML_OR(block, I0, I0, I2); // or i0,i0,i2
+ UML_RET(block); // ret
+
+ UML_LABEL(block, label++); // label1:
+ UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
+ UML_JMPc(block, COND_B, label); // jb label2
+ UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
+ UML_JMPc(block, COND_A, label); // ja label2
+
+ // 0x28000 ... 0x3ffff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff (block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff)
+ UML_MULS(block, I1, I1, I1, 3); // muls i1,3
+ UML_LOAD(block, I0, block1, I1, SIZE_WORD, SCALE_x2); // load i0,[block1],i1,word,scale_x2
+ UML_SHL(block, I0, I0, 16); // shl i0,i0,16
+ UML_LOAD(block, I2, block1_1, I1, SIZE_WORD, SCALE_x2); // load i2,[block1_1],i1,word,scale_x2
+ UML_OR(block, I0, I0, I2); // or i0,i0,i2
+ UML_RET(block); // ret
+
+ UML_LABEL(block, label++); // label2:
+ break;
+
+ case MEM_ACCESSOR_PM_WRITE32:
+ UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
+ UML_JMPc(block, COND_B, label); // jb label1
+ UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
+ UML_JMPc(block, COND_A, label); // ja label1
+
+ // 0x20000 ... 0x27fff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
+ UML_MULS(block, I1, I1, I1, 3); // muls i1,3
+ UML_STORE(block, block0_1, I1, I0, SIZE_WORD, SCALE_x2); // store [block0_1],i1,i0,word,scale_x2
+ UML_SHR(block, I0, I0, 16); // shr i0,i0,16
+ UML_STORE(block, block0, I1, I0, SIZE_WORD, SCALE_x2); // store [block0],i1,i0,word,scale_x2
+ UML_RET(block); // ret
+
+ UML_LABEL(block, label++); // label1:
+ UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
+ UML_JMPc(block, COND_B, label); // jb label2
+ UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
+ UML_JMPc(block, COND_A, label); // ja label2
+
+ // 0x28000 ... 0x3ffff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff (block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff)
+ UML_MULS(block, I1, I1, I1, 3); // muls i1,3
+ UML_STORE(block, block1_1, I1, I0, SIZE_WORD, SCALE_x2); // store [block1_1],i1,i0,word,scale_x2
+ UML_SHR(block, I0, I0, 16); // shr i0,i0,16
+ UML_STORE(block, block1, I1, I0, SIZE_WORD, SCALE_x2); // store [block1],i1,i0,word,scale_x2
+ UML_RET(block); // ret
+
+ UML_LABEL(block, label++); // label2:
+ break;
+
+ case MEM_ACCESSOR_DM_READ32:
+ UML_CMP(block, I1, IRAM_END); // cmp i1,IRAM_END
+ UML_JMPc(block, COND_BE, label); // jbe label1
+ // 0x80000 ...
+ UML_SHL(block, I1, I1, 2); // shl i1,i1,2
+ UML_READ(block, I0, I1, SIZE_DWORD, SPACE_DATA); // read i0,i1,dword,SPACE_DATA
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // label1:
+ UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
+ UML_JMPc(block, COND_B, label); // jb label2
+ UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
+ UML_JMPc(block, COND_A, label); // ja label2
+ // 0x20000 ... 0x27fff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
+ UML_LOAD(block, I0, block0, I1, SIZE_WORD, SCALE_x4); // load i0,[block0],i1,word,scale_x4
+ UML_SHL(block, I0, I0, 16); // shl i0,i0,16
+ UML_LOAD(block, I2, block0_1, I1, SIZE_WORD, SCALE_x4); // load i2,[block0_1],i1,word,scale_x4
+ UML_OR(block, I0, I0, I2); // or i0,i0,i2
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // label2:
+ UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
+ UML_JMPc(block, COND_B, label); // jb label3
+ UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
+ UML_JMPc(block, COND_A, label); // ja label3
+ // 0x28000 ... 0x3ffff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
+ UML_LOAD(block, I0, block1, I1, SIZE_WORD, SCALE_x4); // load i0,[block1],i1,word,scale_x4
+ UML_SHL(block, I0, I0, 16); // shl i0,i0,16
+ UML_LOAD(block, I2, block1_1, I1, SIZE_WORD, SCALE_x4); // load i2,[block1_1],i1,word,scale_x4
+ UML_OR(block, I0, I0, I2); // or i0,i0,i2
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // Label3:
+ UML_CMP(block, I1, IOP_REGISTER_END); // cmp i1,IOP_REGISTER_END
+ UML_JMPc(block, COND_A, label); // ja label4
+ // IOP registers
+ UML_MOV(block, mem(&m_core->arg0), I1); // mov [m_core->arg0],i1
+ UML_CALLC(block, cfunc_read_iop, this); // callc cfunc_read_iop
+ UML_MOV(block, I0, mem(&m_core->arg1)); // mov i0,[m_core->arg1]
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // label4:
+ UML_CMP(block, I1, IRAM_SHORT_BLOCK0_START); // cmp i1,IRAM_SHORT_BLOCK0_START
+ UML_JMPc(block, COND_B, label+1); // jb label6
+ UML_CMP(block, I1, IRAM_SHORT_BLOCK0_END); // cmp i1,IRAM_SHORT_BLOCK0_END
+ UML_JMPc(block, COND_A, label+1); // ja label6
+ // 0x40000 ... 0x4ffff
+ UML_AND(block, I1, I1, 0xffff); // and i1,i1,0xffff
+ UML_XOR(block, I1, I1, 1); // xor i1,i1,1
+ UML_TEST(block, mem(&m_core->mode1), 0x4000); // test [m_core->mode1],0x4000
+ UML_JMPc(block, COND_Z, label); // jz label5
+ UML_LOADS(block, I0, block0, I1, SIZE_WORD, SCALE_x2); // loads i0,[block0],i1,word,scale_x2
+ UML_RET(block);
+ UML_LABEL(block, label++); // label5:
+ UML_LOAD(block, I0, block0, I1, SIZE_WORD, SCALE_x2); // load i0,[block0],i1,word,scale_x2
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // label6:
+ UML_CMP(block, I1, IRAM_SHORT_BLOCK1_START); // cmp i1,IRAM_SHORT_BLOCK1_START
+ UML_JMPc(block, COND_B, label+1); // jb label8
+ UML_CMP(block, I1, IRAM_SHORT_BLOCK1_END); // cmp i1,IRAM_SHORT_BLOCK1_END
+ UML_JMPc(block, COND_A, label+1); // ja label8
+ // 0x50000 ... 0x7ffff
+ UML_AND(block, I1, I1, 0xffff); // and i1,i1,0xffff
+ UML_XOR(block, I1, I1, 1); // xor i1,i1,1
+ UML_TEST(block, mem(&m_core->mode1), 0x4000); // test [m_core->mode1],0x4000
+ UML_JMPc(block, COND_Z, label); // jz label7
+ UML_LOADS(block, I0, block1, I1, SIZE_WORD, SCALE_x2); // loads i0,[block1],i1,word,scale_x2
+ UML_RET(block);
+ UML_LABEL(block, label++); // label7:
+ UML_LOAD(block, I0, block1, I1, SIZE_WORD, SCALE_x2); // load i0,[block1],i1,word,scale_x2
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // label8:
+ break;
+
+ case MEM_ACCESSOR_DM_WRITE32:
+#if WRITE_SNOOP
+ //UML_CMP(block, I1, 0x283eb);
+ UML_CMP(block, I1, 0x2400047);
+ UML_JMPc(block, COND_NE, label);
+ UML_MOV(block, mem(&m_core->arg0), I0);
+ UML_MOV(block, mem(&m_core->arg1), I1);
+ UML_MOV(block, mem(&m_core->arg2), mem(&m_core->pc));
+ UML_CALLC(block, cfunc_write_snoop, this);
+ UML_LABEL(block, label++);
+#endif
+
+
+ UML_CMP(block, I1, IRAM_END); // cmp i1,IRAM_END
+ UML_JMPc(block, COND_BE, label); // jbe label1
+ // 0x80000 ...
+ UML_SHL(block, I1, I1, 2); // shl i1,i1,2
+ UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_DATA); // write i1,i0,dword,SPACE_DATA
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // label1:
+ UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
+ UML_JMPc(block, COND_B, label); // jb label2
+ UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
+ UML_JMPc(block, COND_A, label); // ja label2
+ // 0x20000 ... 0x27fff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
+ UML_STORE(block, block0_1, I1, I0, SIZE_WORD, SCALE_x4); // store [block0_1],i1,i0,word,scale_x4
+ UML_SHR(block, I0, I0, 16); // shr i0,i0,16
+ UML_STORE(block, block0, I1, I0, SIZE_WORD, SCALE_x4); // store [block0],i1,i0,word,scale_x4
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // label2:
+ UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
+ UML_JMPc(block, COND_B, label); // jb label3
+ UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
+ UML_JMPc(block, COND_A, label); // ja label3
+ // 0x28000 ... 0x3ffff
+ UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
+ UML_STORE(block, block1_1, I1, I0, SIZE_WORD, SCALE_x4); // store [block1_1],i1,i0,word,scale_x4
+ UML_SHR(block, I0, I0, 16); // shr i0,i0,16
+ UML_STORE(block, block1, I1, I0, SIZE_WORD, SCALE_x4); // store [block1],i1,i0,word,scale_x4
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // Label3:
+ UML_CMP(block, I1, IOP_REGISTER_END); // cmp i1,IOP_REGISTER_END
+ UML_JMPc(block, COND_A, label); // ja label4
+ // IOP registers
+ UML_MOV(block, mem(&m_core->arg0), I1); // mov [m_core->arg0],i1
+ UML_MOV(block, mem(&m_core->arg1), I0); // mov [m_core->arg1],i0
+ UML_CALLC(block, cfunc_write_iop, this); // callc cfunc_write_iop
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // label4:
+ UML_CMP(block, I1, IRAM_SHORT_BLOCK0_START); // cmp i1,IRAM_SHORT_BLOCK0_START
+ UML_JMPc(block, COND_B, label); // jb label5
+ UML_CMP(block, I1, IRAM_SHORT_BLOCK0_END); // cmp i1,IRAM_SHORT_BLOCK0_END
+ UML_JMPc(block, COND_A, label); // ja label5
+ // 0x40000 ... 0x4ffff
+ UML_AND(block, I1, I1, 0xffff); // and i1,i1,0xffff
+ UML_XOR(block, I1, I1, 1); // xor i1,i1,1
+ UML_STORE(block, block0, I1, I0, SIZE_WORD, SCALE_x2); // store [block0],i1,i0,word,scale_x2
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // label5:
+ UML_CMP(block, I1, IRAM_SHORT_BLOCK1_START); // cmp i1,IRAM_SHORT_BLOCK1_START
+ UML_JMPc(block, COND_B, label); // jb label6
+ UML_CMP(block, I1, IRAM_SHORT_BLOCK1_END); // cmp i1,IRAM_SHORT_BLOCK1_END
+ UML_JMPc(block, COND_A, label); // ja label6
+ // 0x50000 ... 0x7ffff
+ UML_AND(block, I1, I1, 0xffff); // and i1,i1,0xffff
+ UML_XOR(block, I1, I1, 1); // xor i1,i1,1
+ UML_STORE(block, block1, I1, I0, SIZE_WORD, SCALE_x2); // store [block1],i1,i0,word,scale_x2
+ UML_RET(block);
+
+ UML_LABEL(block, label++); // label6:
+ break;
+ }
+
+ UML_RET(block);
+
+ block->end();
+}
+
+void adsp21062_device::static_generate_push_pc()
+{
+ // Push contents of I0 to PC stack
+ // Trashes I1
+
+ code_label label = 1;
+ drcuml_block *block = m_drcuml->begin_block(32);
+
+ // add a global entry for this
+ alloc_handle(m_drcuml.get(), &m_push_pc, "push_pc");
+ UML_HANDLE(block, *m_push_pc); // handle *m_push_pc
+
+ UML_MOV(block, I1, PCSTKP); // mov i1,PCSTKP
+ UML_ADD(block, I1, I1, 1); // add i1,i1,1
+ UML_CMP(block, I1, 32); // cmp i1,32
+ UML_JMPc(block, COND_L,label); // jl label1
+ UML_CALLC(block, cfunc_pcstack_overflow, this); // callc cfunc_pcstack_overflow
+
+ UML_LABEL(block, label++); // label1:
+ UML_CMP(block, I1, 0); // cmp i1,0
+ UML_JMPc(block, COND_E, label); // je label2
+ UML_AND(block, STKY, STKY, ~0x400000); // and STKY,~0x400000
+ UML_JMP(block, label + 1); // jmp label3
+ UML_LABEL(block, label++); // label2:
+ UML_OR(block, STKY, STKY, 0x400000); // or STKY,0x400000
+
+ UML_LABEL(block, label++); // label3:
+ UML_MOV(block, PCSTK, I0); // mov PCSTK,pc
+ UML_STORE(block, &m_core->pcstack, I1, I0, SIZE_DWORD, SCALE_x4); // store [m_core->pcstack],i1,i0,dword,scale_x4
+ UML_MOV(block, PCSTKP, I1); // mov PCSTKP,i1
+
+ UML_RET(block);
+
+ block->end();
+}
+
+void adsp21062_device::static_generate_pop_pc()
+{
+ // Pop PC stack into I0
+ // Trashes I1
+
+ code_label label = 1;
+ drcuml_block *block = m_drcuml->begin_block(32);
+
+ // add a global entry for this
+ alloc_handle(m_drcuml.get(), &m_pop_pc, "pop_pc");
+ UML_HANDLE(block, *m_pop_pc); // handle *m_pop_pc
+
+ UML_MOV(block, I1, PCSTKP); // mov i0,PCSTKP
+ UML_LOAD(block, I0, &m_core->pcstack, I1, SIZE_DWORD, SCALE_x4); // load i1,[m_core->pcstack],i0,dword,scale_x4
+ UML_CMP(block, I1, 0); // cmp i1,0
+ UML_JMPc(block, COND_NE, label); // jne label1
+ UML_CALLC(block, cfunc_pcstack_underflow, this); // callc cfunc_pcstack_underflow
+
+ UML_LABEL(block, label++); // label1:
+ UML_SUB(block, I1, I1, 1); // sub i1,i1,1
+ UML_CMP(block, I1, 0); // cmp i1,0
+ UML_JMPc(block, COND_E, label); // je label2
+ UML_AND(block, STKY, STKY, ~0x400000); // and STKY,~0x400000
+ UML_JMP(block, label + 1); // jmp label3
+ UML_LABEL(block, label++); // label2:
+ UML_OR(block, STKY, STKY, 0x400000); // or STKY,0x400000
+
+ UML_LABEL(block, label++); // label3:
+ UML_MOV(block, PCSTKP, I1); // mov PCSTKP,i1
+ UML_MOV(block, PCSTK, I0); // mov PCSTK,i0
+
+ UML_RET(block);
+
+ block->end();
+}
+
+void adsp21062_device::static_generate_push_loop()
+{
+ // I0 = counter
+ // I1 = type/condition/addr
+ // Trashes I2
+
+ code_label label = 1;
+ drcuml_block *block = m_drcuml->begin_block(32);
+
+ // add a global entry for this
+ alloc_handle(m_drcuml.get(), &m_push_loop, "push_loop");
+ UML_HANDLE(block, *m_push_loop); // handle *m_push_loop
+
+ UML_MOV(block, I2, LSTKP); // mov i2,LSTKP
+ UML_ADD(block, I2, I2, 1); // add i2,1
+ UML_CMP(block, I2, 6); // cmp i2,6
+ UML_JMPc(block, COND_L, label); // jl label1
+ UML_CALLC(block, cfunc_loopstack_overflow, this); // callc cfunc_loopstack_overflow
+
+ UML_LABEL(block, label++); // label1:
+ UML_CMP(block, I2, 0); // cmp i2,0
+ UML_JMPc(block, COND_E, label); // je label2
+ UML_AND(block, STKY, STKY, ~0x4000000); // and STKY,~0x4000000
+ UML_JMP(block, label + 1); // jmp label3
+ UML_LABEL(block, label++); // label2:
+ UML_OR(block, STKY, STKY, 0x4000000); // or STKY,0x4000000
+
+ UML_LABEL(block, label++); // label3:
+
+ UML_STORE(block, m_core->lcstack, I2, I0, SIZE_DWORD, SCALE_x4); // store m_core->lcstack,i2,i0,dword,scale_x4
+ UML_STORE(block, m_core->lastack, I2, I1, SIZE_DWORD, SCALE_x4); // store m_core->lastack,i2,i1,dword,scale_x4
+ UML_MOV(block, CURLCNTR, I0); // mov CURLCNTR,i0
+ UML_MOV(block, LSTKP, I2); // mov LSTKP,i2
+
+ UML_RET(block);
+
+ block->end();
+}
+
+void adsp21062_device::static_generate_pop_loop()
+{
+ // Trashes I0,I2
+
+ code_label label = 1;
+ drcuml_block *block = m_drcuml->begin_block(32);
+
+ // add a global entry for this
+ alloc_handle(m_drcuml.get(), &m_pop_loop, "pop_loop");
+ UML_HANDLE(block, *m_pop_loop); // handle *m_pop_loop
+
+ UML_MOV(block, I2, LSTKP); // mov i2,LSTKP
+ UML_CMP(block, I2, 0); // cmp i2,0
+ UML_JMPc(block, COND_NE, label); // jne label1
+ UML_CALLC(block, cfunc_loopstack_underflow, this); // callc cfunc_loopstack_underflow
+
+ UML_LABEL(block, label++); // label1:
+ UML_SUB(block, I2, I2, 1); // sub i2,i2,1
+ UML_CMP(block, I2, 0); // cmp i2,0
+ UML_JMPc(block, COND_E, label); // je label2
+ UML_AND(block, STKY, STKY, ~0x4000000); // and STKY,~0x4000000
+ UML_JMP(block, label + 1); // jmp label3
+ UML_LABEL(block, label++); // label2:
+ UML_OR(block, STKY, STKY, 0x4000000); // or STKY,0x4000000
+
+ UML_LABEL(block, label++); // label3:
+ UML_LOAD(block, I0, m_core->lcstack, I2, SIZE_DWORD, SCALE_x4); // load i0,m_core->lcstack,i2,dword,scale_x4
+ UML_MOV(block, CURLCNTR, I0); // mov CURLCNTR,i0
+ UML_MOV(block, LSTKP, I2); // mov LSTKP,i2
+
+ UML_RET(block);
+
+ block->end();
+}
+
+void adsp21062_device::static_generate_push_status()
+{
+ // Trashes I2
+
+ code_label label = 1;
+ drcuml_block *block = m_drcuml->begin_block(32);
+
+ // add a global entry for this
+ alloc_handle(m_drcuml.get(), &m_push_status, "push_status");
+ UML_HANDLE(block, *m_push_status); // handle *m_push_status
+
+ UML_MOV(block, I2, mem(&m_core->status_stkp)); // mov i2,[status_stkp]
+ UML_ADD(block, I2, I2, 1); // add i2,1
+ UML_CMP(block, I2, 5); // cmp i2,5
+ UML_JMPc(block, COND_L, label); // jl label1
+ UML_CALLC(block, cfunc_statusstack_overflow, this); // callc cfunc_statusstack_overflow
+
+ UML_LABEL(block, label++); // label1:
+ UML_CMP(block, I2, 0); // cmp i2,0
+ UML_JMPc(block, COND_E, label); // je label2
+ UML_AND(block, STKY, STKY, ~0x1000000); // and STKY,~0x1000000
+ UML_JMP(block, label + 1); // jmp label3
+ UML_LABEL(block, label++); // label2:
+ UML_OR(block, STKY, STKY, 0x1000000); // or STKY,0x1000000
+
+ UML_LABEL(block, label++); // label3:
+ UML_MOV(block, mem(&m_core->status_stkp), I2); // mov [status_stkp],i2
+
+ //TODO: load MODE1
+ //TODO: load ASTAT
+
+ UML_RET(block);
+
+ block->end();
+}
+
+void adsp21062_device::static_generate_pop_status()
+{
+ // Trashes I2
+
+ code_label label = 1;
+ drcuml_block *block = m_drcuml->begin_block(32);
+
+ // add a global entry for this
+ alloc_handle(m_drcuml.get(), &m_pop_status, "pop_status");
+ UML_HANDLE(block, *m_pop_status); // handle *m_pop_status
+
+ //TODO: store MODE1
+ //TODO: store ASTAT
+
+ UML_MOV(block, I2, mem(&m_core->status_stkp)); // mov i2,[status_stkp]
+ UML_CMP(block, I2, 0); // cmp i2,0
+ UML_JMPc(block, COND_NE, label); // jl label1
+ UML_CALLC(block, cfunc_statusstack_underflow, this); // callc cfunc_statusstack_underflow
+
+ UML_LABEL(block, label++); // label1:
+ UML_SUB(block, I2, I2, 1); // sub i2,1
+ UML_CMP(block, I2, 0); // cmp i2,0
+ UML_JMPc(block, COND_E, label); // je label2
+ UML_AND(block, STKY, STKY, ~0x1000000); // and STKY,~0x1000000
+ UML_JMP(block, label + 1); // jmp label3
+ UML_LABEL(block, label++); // label2:
+ UML_OR(block, STKY, STKY, 0x1000000); // or STKY,0x1000000
+
+ UML_LABEL(block, label++); // label3:
+ UML_MOV(block, mem(&m_core->status_stkp), I2); // mov [status_stkp],i2
+
+ UML_RET(block);
+
+ block->end();
+}
+
+
+void adsp21062_device::static_generate_exception(UINT8 exception, const char *name)
+{
+ code_handle *&exception_handle = m_exception[exception];
+
+ code_label label = 1;
+
+ code_label label_nopush = label++;
+
+ /* begin generating */
+ drcuml_block *block = m_drcuml->begin_block(1024);
+
+ /* add a global entry for this */
+ alloc_handle(m_drcuml.get(), &exception_handle, name);
+ UML_HANDLE(block, *exception_handle); // handle name
+
+ UML_AND(block, I3, mem(&m_core->irq_pending), IMASK); // and i3,[irq_pending],IMASK
+ UML_TZCNT(block, I3, I3); // tzcnt i3,i3
+
+ UML_MOV(block, I2, 1); // mov i2,1
+ UML_SHL(block, I2, I2, I3); // shl i2,i2,i3
+ UML_OR(block, IRPTL, IRPTL, I2); // or IRPTL,i2
+ UML_XOR(block, mem(&m_core->irq_pending), mem(&m_core->irq_pending), I2); // xor [irq_pending],i2
+ UML_MOV(block, mem(&m_core->active_irq_num), I3); // mov [active_irq_num],i3
+ UML_MOV(block, mem(&m_core->interrupt_active), 1); // mov [interrupt_active],1
+
+ UML_CALLH(block, *m_push_pc); // callh m_push_pc
+
+ UML_CMP(block, I3, 6); // cmp i3,6
+ UML_JMPc(block, COND_L, label_nopush); // jl label_nopush
+ UML_CMP(block, I3, 8); // cmp i3,8
+ UML_JMPc(block, COND_G, label_nopush); // jg label_nopush
+ UML_CALLH(block, *m_push_status); // callh m_push_status
+
+ UML_LABEL(block, label_nopush); // label_nopush:
+ UML_SHL(block, I0, I3, 2); // shl i0,i3,2
+ UML_ADD(block, I0, I0, 0x20000); // add i0,0x20000
+ UML_HASHJMP(block, 0, I0, *m_nocode); // hashjmp i0,m_nocode
+
+ block->end();
+}
+
+
+void adsp21062_device::static_generate_mode1_ops()
+{
+ drcuml_block *block;
+
+ // TODO: these could be further optimized with 64-bit or 128-bit swaps
+ // e.g SWAP128 instruction (swap 128 bits between 2 memory locations)
+
+ block = m_drcuml->begin_block(128);
+ alloc_handle(m_drcuml.get(), &m_swap_dag1_0_3, "swap_dag1_0_3");
+ UML_HANDLE(block, *m_swap_dag1_0_3); // handle name
+#if !USE_SWAPDQ
+ for (int i = 0; i < 4; i++)
+ {
+ UML_MOV(block, I0, mem(&m_core->dag1.i[i]));
+ UML_MOV(block, I1, mem(&m_core->dag1_alt.i[i]));
+ UML_MOV(block, mem(&m_core->dag1.i[i]), I1);
+ UML_MOV(block, mem(&m_core->dag1_alt.i[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag1.m[i]));
+ UML_MOV(block, I1, mem(&m_core->dag1_alt.m[i]));
+ UML_MOV(block, mem(&m_core->dag1.m[i]), I1);
+ UML_MOV(block, mem(&m_core->dag1_alt.m[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag1.l[i]));
+ UML_MOV(block, I1, mem(&m_core->dag1_alt.l[i]));
+ UML_MOV(block, mem(&m_core->dag1.l[i]), I1);
+ UML_MOV(block, mem(&m_core->dag1_alt.l[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag1.b[i]));
+ UML_MOV(block, I1, mem(&m_core->dag1_alt.b[i]));
+ UML_MOV(block, mem(&m_core->dag1.b[i]), I1);
+ UML_MOV(block, mem(&m_core->dag1_alt.b[i]), I0);
+ }
+#else
+ UML_SWAPDQ(block, mem(&m_core->dag1.i[0]), mem(&m_core->dag1_alt.i[0]));
+ UML_SWAPDQ(block, mem(&m_core->dag1.m[0]), mem(&m_core->dag1_alt.m[0]));
+ UML_SWAPDQ(block, mem(&m_core->dag1.l[0]), mem(&m_core->dag1_alt.l[0]));
+ UML_SWAPDQ(block, mem(&m_core->dag1.b[0]), mem(&m_core->dag1_alt.b[0]));
+#endif
+ UML_RET(block);
+ block->end();
+
+ block = m_drcuml->begin_block(128);
+ alloc_handle(m_drcuml.get(), &m_swap_dag1_4_7, "swap_dag1_4_7");
+ UML_HANDLE(block, *m_swap_dag1_4_7); // handle name
+#if !USE_SWAPDQ
+ for (int i = 4; i < 8; i++)
+ {
+ UML_MOV(block, I0, mem(&m_core->dag1.i[i]));
+ UML_MOV(block, I1, mem(&m_core->dag1_alt.i[i]));
+ UML_MOV(block, mem(&m_core->dag1.i[i]), I1);
+ UML_MOV(block, mem(&m_core->dag1_alt.i[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag1.m[i]));
+ UML_MOV(block, I1, mem(&m_core->dag1_alt.m[i]));
+ UML_MOV(block, mem(&m_core->dag1.m[i]), I1);
+ UML_MOV(block, mem(&m_core->dag1_alt.m[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag1.l[i]));
+ UML_MOV(block, I1, mem(&m_core->dag1_alt.l[i]));
+ UML_MOV(block, mem(&m_core->dag1.l[i]), I1);
+ UML_MOV(block, mem(&m_core->dag1_alt.l[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag1.b[i]));
+ UML_MOV(block, I1, mem(&m_core->dag1_alt.b[i]));
+ UML_MOV(block, mem(&m_core->dag1.b[i]), I1);
+ UML_MOV(block, mem(&m_core->dag1_alt.b[i]), I0);
+ }
+#else
+ UML_SWAPDQ(block, mem(&m_core->dag1.i[4]), mem(&m_core->dag1_alt.i[4]));
+ UML_SWAPDQ(block, mem(&m_core->dag1.m[4]), mem(&m_core->dag1_alt.m[4]));
+ UML_SWAPDQ(block, mem(&m_core->dag1.l[4]), mem(&m_core->dag1_alt.l[4]));
+ UML_SWAPDQ(block, mem(&m_core->dag1.b[4]), mem(&m_core->dag1_alt.b[4]));
+#endif
+ UML_RET(block);
+ block->end();
+
+ block = m_drcuml->begin_block(128);
+ alloc_handle(m_drcuml.get(), &m_swap_dag2_0_3, "swap_dag2_0_3");
+ UML_HANDLE(block, *m_swap_dag2_0_3); // handle name
+#if !USE_SWAPDQ
+ for (int i = 0; i < 4; i++)
+ {
+ UML_MOV(block, I0, mem(&m_core->dag2.i[i]));
+ UML_MOV(block, I1, mem(&m_core->dag2_alt.i[i]));
+ UML_MOV(block, mem(&m_core->dag2.i[i]), I1);
+ UML_MOV(block, mem(&m_core->dag2_alt.i[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag2.m[i]));
+ UML_MOV(block, I1, mem(&m_core->dag2_alt.m[i]));
+ UML_MOV(block, mem(&m_core->dag2.m[i]), I1);
+ UML_MOV(block, mem(&m_core->dag2_alt.m[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag2.l[i]));
+ UML_MOV(block, I1, mem(&m_core->dag2_alt.l[i]));
+ UML_MOV(block, mem(&m_core->dag2.l[i]), I1);
+ UML_MOV(block, mem(&m_core->dag2_alt.l[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag2.b[i]));
+ UML_MOV(block, I1, mem(&m_core->dag2_alt.b[i]));
+ UML_MOV(block, mem(&m_core->dag2.b[i]), I1);
+ UML_MOV(block, mem(&m_core->dag2_alt.b[i]), I0);
+ }
+#else
+ UML_SWAPDQ(block, mem(&m_core->dag2.i[0]), mem(&m_core->dag2_alt.i[0]));
+ UML_SWAPDQ(block, mem(&m_core->dag2.m[0]), mem(&m_core->dag2_alt.m[0]));
+ UML_SWAPDQ(block, mem(&m_core->dag2.l[0]), mem(&m_core->dag2_alt.l[0]));
+ UML_SWAPDQ(block, mem(&m_core->dag2.b[0]), mem(&m_core->dag2_alt.b[0]));
+#endif
+ UML_RET(block);
+ block->end();
+
+ block = m_drcuml->begin_block(128);
+ alloc_handle(m_drcuml.get(), &m_swap_dag2_4_7, "swap_dag2_4_7");
+ UML_HANDLE(block, *m_swap_dag2_4_7); // handle name
+#if !USE_SWAPDQ
+ for (int i = 4; i < 8; i++)
+ {
+ UML_MOV(block, I0, mem(&m_core->dag2.i[i]));
+ UML_MOV(block, I1, mem(&m_core->dag2_alt.i[i]));
+ UML_MOV(block, mem(&m_core->dag2.i[i]), I1);
+ UML_MOV(block, mem(&m_core->dag2_alt.i[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag2.m[i]));
+ UML_MOV(block, I1, mem(&m_core->dag2_alt.m[i]));
+ UML_MOV(block, mem(&m_core->dag2.m[i]), I1);
+ UML_MOV(block, mem(&m_core->dag2_alt.m[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag2.l[i]));
+ UML_MOV(block, I1, mem(&m_core->dag2_alt.l[i]));
+ UML_MOV(block, mem(&m_core->dag2.l[i]), I1);
+ UML_MOV(block, mem(&m_core->dag2_alt.l[i]), I0);
+ UML_MOV(block, I0, mem(&m_core->dag2.b[i]));
+ UML_MOV(block, I1, mem(&m_core->dag2_alt.b[i]));
+ UML_MOV(block, mem(&m_core->dag2.b[i]), I1);
+ UML_MOV(block, mem(&m_core->dag2_alt.b[i]), I0);
+ }
+#else
+ UML_SWAPDQ(block, mem(&m_core->dag2.i[4]), mem(&m_core->dag2_alt.i[4]));
+ UML_SWAPDQ(block, mem(&m_core->dag2.m[4]), mem(&m_core->dag2_alt.m[4]));
+ UML_SWAPDQ(block, mem(&m_core->dag2.l[4]), mem(&m_core->dag2_alt.l[4]));
+ UML_SWAPDQ(block, mem(&m_core->dag2.b[4]), mem(&m_core->dag2_alt.b[4]));
+#endif
+ UML_RET(block);
+ block->end();
+
+ block = m_drcuml->begin_block(64);
+ alloc_handle(m_drcuml.get(), &m_swap_r0_7, "swap_r0_7");
+ UML_HANDLE(block, *m_swap_r0_7); // handle name
+#if !USE_SWAPDQ
+ for (int i = 0; i < 8; i++)
+ {
+ UML_MOV(block, I0, mem(&m_core->r[i]));
+ UML_MOV(block, I1, mem(&m_core->reg_alt[i]));
+ UML_MOV(block, mem(&m_core->r[i]), I1);
+ UML_MOV(block, mem(&m_core->reg_alt[i]), I0);
+ }
+#else
+ UML_SWAPDQ(block, mem(&m_core->r[0]), mem(&m_core->reg_alt[0]));
+ UML_SWAPDQ(block, mem(&m_core->r[4]), mem(&m_core->reg_alt[4]));
+#endif
+ UML_RET(block);
+ block->end();
+
+ block = m_drcuml->begin_block(64);
+ alloc_handle(m_drcuml.get(), &m_swap_r8_15, "swap_r8_15");
+ UML_HANDLE(block, *m_swap_r8_15); // handle name
+#if !USE_SWAPDQ
+ for (int i = 8; i < 16; i++)
+ {
+ UML_MOV(block, I0, mem(&m_core->r[i]));
+ UML_MOV(block, I1, mem(&m_core->reg_alt[i]));
+ UML_MOV(block, mem(&m_core->r[i]), I1);
+ UML_MOV(block, mem(&m_core->reg_alt[i]), I0);
+ }
+#else
+ UML_SWAPDQ(block, mem(&m_core->r[8]), mem(&m_core->reg_alt[8]));
+ UML_SWAPDQ(block, mem(&m_core->r[12]), mem(&m_core->reg_alt[12]));
+#endif
+ UML_RET(block);
+ block->end();
+}
+
+
+
+
+void adsp21062_device::execute_run_drc()
+{
+ drcuml_state *drcuml = m_drcuml.get();
+ int execute_result;
+
+// if (m_cache_dirty)
+// printf("SHARC cache reset\n");
+
+ /* reset the cache if dirty */
+ if (m_cache_dirty)
+ flush_cache();
+
+ m_cache_dirty = false;
+ m_core->force_recompile = 0;
+
+ /* execute */
+ do
+ {
+ execute_result = drcuml->execute(*m_entry);
+
+ /* if we need to recompile, do it */
+ if (execute_result == EXECUTE_MISSING_CODE)
+ {
+ compile_block(m_core->pc);
+ }
+ else if (execute_result == EXECUTE_UNMAPPED_CODE)
+ {
+ fatalerror("Attempted to execute unmapped code at PC=%08X\n", m_core->pc);
+ }
+ else if (execute_result == EXECUTE_RESET_CACHE)
+ {
+ flush_cache();
+ }
+ } while (execute_result != EXECUTE_OUT_OF_CYCLES);
+}
+
+
+void adsp21062_device::compile_block(offs_t pc)
+{
+ compiler_state compiler = { 0 };
+
+ const opcode_desc *seqhead, *seqlast;
+ const opcode_desc *desclist;
+ bool override = false;
+
+ drcuml_block *block;
+
+ desclist = m_drcfe->describe_code(pc);
+
+ bool succeeded = false;
+ while (!succeeded)
+ {
+ try
+ {
+ block = m_drcuml->begin_block(4096);
+
+ for (seqhead = desclist; seqhead != nullptr; seqhead = seqlast->next())
+ {
+ const opcode_desc *curdesc;
+ UINT32 nextpc;
+
+ /* determine the last instruction in this sequence */
+ for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
+ if (seqlast->flags & OPFLAG_END_SEQUENCE)
+ break;
+ assert(seqlast != nullptr);
+
+ /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */
+ if (override || m_drcuml->hash_exists(0, seqhead->pc))
+ UML_HASH(block, 0, seqhead->pc); // hash mode,pc
+
+ /* if we already have a hash, and this is the first sequence, assume that we */
+ /* are recompiling due to being out of sync and allow future overrides */
+ else if (seqhead == desclist)
+ {
+ override = true;
+ UML_HASH(block, 0, seqhead->pc); // hash mode,pc
+ }
+
+ /* otherwise, redispatch to that fixed PC and skip the rest of the processing */
+ else
+ {
+ UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc
+ UML_HASHJMP(block, 0, seqhead->pc, *m_nocode); // hashjmp <0>,seqhead->pc,nocode
+ continue;
+ }
+
+ /* label this instruction, if it may be jumped to locally */
+ if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
+ UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc
+
+ /* iterate over instructions in the sequence and compile them */
+ for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next())
+ generate_sequence_instruction(block, &compiler, curdesc);
+
+ /* if we need to return to the start, do it */
+ if (seqlast->flags & OPFLAG_RETURN_TO_START)
+ nextpc = pc;
+ /* otherwise we just go to the next instruction */
+ else
+ nextpc = seqlast->pc + (seqlast->skipslots + 1);
+
+
+ // force recompilation at end of block, if needed
+ UML_CMP(block, mem(&m_core->force_recompile), 0);
+ UML_JMPc(block, COND_Z, compiler.labelnum);
+ UML_MOV(block, mem(&m_cache_dirty), 1);
+ UML_MOV(block, mem(&m_core->icount), 0);
+ UML_LABEL(block, compiler.labelnum++);
+
+
+ /* count off cycles and go there */
+ generate_update_cycles(block, &compiler, nextpc, TRUE); // <subtract cycles>
+
+ if (seqlast->next() == nullptr || seqlast->next()->pc != nextpc)
+ UML_HASHJMP(block, 0, nextpc, *m_nocode); // hashjmp <mode>,nextpc,nocode
+ }
+
+ block->end();
+ succeeded = true;
+ }
+ catch (drcuml_block::abort_compilation &)
+ {
+ flush_cache();
+ }
+ }
+}
+
+
+void adsp21062_device::flush_cache()
+{
+ /* empty the transient cache contents */
+ m_drcuml->reset();
+
+ m_drcfe->flush();
+
+ try
+ {
+ // generate the entry point and out-of-cycles handlers
+ static_generate_entry_point();
+ static_generate_nocode_handler();
+ static_generate_out_of_cycles();
+
+ // generate utility functions
+ static_generate_push_pc();
+ static_generate_pop_pc();
+ static_generate_push_loop();
+ static_generate_pop_loop();
+ static_generate_push_status();
+ static_generate_pop_status();
+ static_generate_mode1_ops();
+
+ // generate exception handlers
+ static_generate_exception(EXCEPTION_INTERRUPT, "exception_interrupt");
+
+ // generate memory accessors
+ static_generate_memory_accessor(MEM_ACCESSOR_PM_READ48, "pm_read48", m_pm_read48);
+ static_generate_memory_accessor(MEM_ACCESSOR_PM_WRITE48, "pm_write48", m_pm_write48);
+ static_generate_memory_accessor(MEM_ACCESSOR_PM_READ32, "pm_read32", m_pm_read32);
+ static_generate_memory_accessor(MEM_ACCESSOR_PM_WRITE32, "pm_write32", m_pm_write32);
+ static_generate_memory_accessor(MEM_ACCESSOR_DM_READ32, "dm_read32", m_dm_read32);
+ static_generate_memory_accessor(MEM_ACCESSOR_DM_WRITE32, "dm_write32", m_dm_write32);
+ }
+ catch (drcuml_block::abort_compilation &)
+ {
+ fatalerror("Error generating SHARC static handlers\n");
+ }
+}
+
+
+void adsp21062_device::static_generate_entry_point()
+{
+ code_label skip = 1;
+ drcuml_block *block;
+
+ /* begin generating */
+ block = m_drcuml->begin_block(20);
+
+ /* forward references */
+ alloc_handle(m_drcuml.get(), &m_nocode, "nocode");
+ alloc_handle(m_drcuml.get(), &m_exception[EXCEPTION_INTERRUPT], "exception_interrupt");
+
+ alloc_handle(m_drcuml.get(), &m_entry, "entry");
+ UML_HANDLE(block, *m_entry); // handle entry
+
+ load_fast_iregs(block); // <load fastregs>
+
+ /* check for interrupts */
+ UML_CMP(block, mem(&m_core->irq_pending), 0); // cmp [irq_pending],0
+ UML_JMPc(block, COND_E, skip); // je skip
+ UML_CMP(block, mem(&m_core->interrupt_active), 0); // cmp [interrupt_active],0
+ UML_JMPc(block, COND_NE, skip); // jne skip
+ UML_TEST(block, mem(&m_core->irq_pending), IMASK); // test [irq_pending],IMASK
+ UML_JMPc(block, COND_Z, skip); // jz skip
+ UML_TEST(block, mem(&m_core->mode1), MODE1_IRPTEN); // test MODE1,MODE1_IRPTEN
+ UML_JMPc(block, COND_Z, skip); // jz skip
+
+ UML_MOV(block, I0, mem(&m_core->pc)); // mov i0,nextpc
+ UML_MOV(block, I1, 0); // mov i1,0
+ UML_CALLH(block, *m_exception[EXCEPTION_INTERRUPT]); // callh m_exception[EXCEPTION_INTERRUPT]
+
+ UML_LABEL(block, skip);
+
+ /* generate a hash jump via the current mode and PC */
+ UML_HASHJMP(block, 0, mem(&m_core->pc), *m_nocode); // hashjmp <mode>,<pc>,nocode
+
+ block->end();
+}
+
+
+void adsp21062_device::static_generate_nocode_handler()
+{
+ drcuml_block *block;
+
+ /* begin generating */
+ block = m_drcuml->begin_block(10);
+
+ /* generate a hash jump via the current mode and PC */
+ alloc_handle(m_drcuml.get(), &m_nocode, "nocode");
+ UML_HANDLE(block, *m_nocode); // handle nocode
+ UML_GETEXP(block, I0); // getexp i0
+ UML_MOV(block, mem(&m_core->pc), I0); // mov [pc],i0
+ save_fast_iregs(block); // <save fastregs>
+ UML_EXIT(block, EXECUTE_MISSING_CODE); // exit EXECUTE_MISSING_CODE
+
+ block->end();
+}
+
+void adsp21062_device::static_generate_out_of_cycles()
+{
+ drcuml_block *block;
+
+ /* begin generating */
+ block = m_drcuml->begin_block(10);
+
+ /* generate a hash jump via the current mode and PC */
+ alloc_handle(m_drcuml.get(), &m_out_of_cycles, "out_of_cycles");
+ UML_HANDLE(block, *m_out_of_cycles); // handle out_of_cycles
+ UML_GETEXP(block, I0); // getexp i0
+ UML_MOV(block, mem(&m_core->pc), I0); // mov <pc>,i0
+ save_fast_iregs(block); // <save fastregs>
+ UML_EXIT(block, EXECUTE_OUT_OF_CYCLES); // exit EXECUTE_OUT_OF_CYCLES
+
+ block->end();
+}
+
+
+void adsp21062_device::generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
+{
+ /* add an entry for the log */
+// if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
+// log_add_disasm_comment(block, desc->pc, desc->opptr.l[0]);
+
+ /* set the PC map variable */
+ UML_MAPVAR(block, MAPVAR_PC, desc->pc); // mapvar PC,desc->pc
+
+ /* accumulate total cycles */
+ compiler->cycles += desc->cycles;
+
+ /* update the icount map variable */
+ UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles); // mapvar CYCLES,compiler->cycles
+
+ /* if we are debugging, call the debugger */
+ if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
+ {
+ UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc
+ save_fast_iregs(block); // <save fastregs>
+ UML_DEBUG(block, desc->pc); // debug desc->pc
+ }
+
+ /* if we hit an unmapped address, fatal error */
+ if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
+ {
+ UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc
+ save_fast_iregs(block); // <save fastregs>
+ UML_EXIT(block, EXECUTE_UNMAPPED_CODE); // exit EXECUTE_UNMAPPED_CODE
+ }
+
+ /* if this is an invalid opcode, generate the exception now */
+// if (desc->flags & OPFLAG_INVALID_OPCODE)
+// UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000); // exh exception_program,0x80000
+
+ /* unless this is a virtual no-op, it's a regular instruction */
+ if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
+ {
+ /* compile the instruction */
+ if (!generate_opcode(block, compiler, desc))
+ {
+ UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr.q[0]); // dmov [arg64],*desc->opptr.q
+ UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented,ppc
+ }
+ }
+
+
+ // insert delayed MODE1 operation if needed
+ if (compiler->mode1_delay.counter > 0)
+ {
+ compiler->mode1_delay.counter--;
+ if (compiler->mode1_delay.counter <= 0)
+ {
+ switch (compiler->mode1_delay.mode)
+ {
+ case MODE1_WRITE_IMM:
+ generate_write_mode1_imm(block, compiler, desc, compiler->mode1_delay.data);
+ break;
+ case MODE1_WRITE_REG:
+ fatalerror("MODE1 delay REG");
+ break;
+ case MODE1_SET:
+ generate_set_mode1_imm(block, compiler, desc, compiler->mode1_delay.data);
+ break;
+ case MODE1_CLEAR:
+ generate_clear_mode1_imm(block, compiler, desc, compiler->mode1_delay.data);
+ break;
+ case MODE1_TOGGLE:
+ fatalerror("MODE1 delay TOGGLE");
+ break;
+ }
+ }
+ }
+
+
+ // insert loop check at this instruction if needed
+ if (desc->userflags & OP_USERFLAG_COUNTER_LOOP)
+ {
+ code_label label_expire = compiler->labelnum++;
+ UML_MOV(block, I1, mem(&m_core->lstkp)); // mov i1,[m_core->lstkp]
+ UML_LOAD(block, I0, m_core->lcstack, I1, SIZE_DWORD, SCALE_x4); // load i0,m_core->lcstack,i1,dword,scale_x4
+ UML_SUB(block, I0, I0, 1); // sub i0,1
+ UML_STORE(block, m_core->lcstack, I1, I0, SIZE_DWORD, SCALE_x4); // store m_core->lcstack,i1,i0,dword,scale_x4
+ UML_SUB(block, CURLCNTR, CURLCNTR, 1); // sub CURLCNTR,1
+ UML_JMPc(block, COND_E, label_expire); // jne label_expire
+
+ generate_jump(block, compiler, desc, false, false, false);
+
+ UML_LABEL(block, label_expire); // label_expire:
+ UML_CALLH(block, *m_pop_pc); // callh m_pop_pc
+ UML_CALLH(block, *m_pop_loop); // callh m_pop_loop
+ }
+ if (desc->userflags & OP_USERFLAG_COND_LOOP)
+ {
+ code_label label_expire = compiler->labelnum++;
+
+ int condition = (desc->userflags & OP_USERFLAG_COND_FIELD) >> OP_USERFLAG_COND_FIELD_SHIFT;
+ generate_do_condition(block, compiler, desc, condition, label_expire, m_core->astat_delay_copy);
+
+ generate_jump(block, compiler, desc, false, false, false);
+
+ UML_LABEL(block, label_expire);
+ UML_CALLH(block, *m_pop_pc);
+ UML_CALLH(block, *m_pop_loop);
+ }
+
+ // copy ASTAT bits over for conditional loop
+ if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY)
+ {
+ if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AZ)
+ UML_MOV(block, mem(&m_core->astat_delay_copy.az), mem(&m_core->astat_drc.az));
+ if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AN)
+ UML_MOV(block, mem(&m_core->astat_delay_copy.an), mem(&m_core->astat_drc.an));
+ if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AV)
+ UML_MOV(block, mem(&m_core->astat_delay_copy.av), mem(&m_core->astat_drc.av));
+ if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AC)
+ UML_MOV(block, mem(&m_core->astat_delay_copy.ac), mem(&m_core->astat_drc.ac));
+ if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_MN)
+ UML_MOV(block, mem(&m_core->astat_delay_copy.mn), mem(&m_core->astat_drc.mn));
+ if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_MV)
+ UML_MOV(block, mem(&m_core->astat_delay_copy.mv), mem(&m_core->astat_drc.mv));
+ if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_SV)
+ UML_MOV(block, mem(&m_core->astat_delay_copy.sv), mem(&m_core->astat_drc.sv));
+ if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_SZ)
+ UML_MOV(block, mem(&m_core->astat_delay_copy.sz), mem(&m_core->astat_drc.sz));
+ if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_BTF)
+ UML_MOV(block, mem(&m_core->astat_delay_copy.btf), mem(&m_core->astat_drc.btf));
+ }
+}
+
+void adsp21062_device::generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, int allow_exception)
+{
+ /* check full interrupts if pending */
+ if (compiler->checkints)
+ {
+ code_label skip = compiler->labelnum++;
+ compiler->checkints = FALSE;
+
+ UML_CMP(block, mem(&m_core->irq_pending), 0); // cmp [irq_pending],0
+ UML_JMPc(block, COND_E, skip); // je skip
+ UML_CMP(block, mem(&m_core->interrupt_active), 0); // cmp [interrupt_active],0
+ UML_JMPc(block, COND_NE, skip); // jne skip
+ UML_TEST(block, mem(&m_core->irq_pending), IMASK); // test [irq_pending],IMASK
+ UML_JMPc(block, COND_Z, skip); // jz skip
+ UML_TEST(block, mem(&m_core->mode1), MODE1_IRPTEN); // test MODE1,MODE1_IRPTEN
+ UML_JMPc(block, COND_Z, skip); // jz skip
+
+ UML_MOV(block, I0, param); // mov i0,nextpc
+ UML_MOV(block, I1, compiler->cycles); // mov i1,cycles
+ UML_CALLH(block, *m_exception[EXCEPTION_INTERRUPT]); // callh m_exception[EXCEPTION_INTERRUPT]
+
+ UML_LABEL(block, skip);
+ }
+
+ /* account for cycles */
+ if (compiler->cycles > 0)
+ {
+ UML_SUB(block, mem(&m_core->icount), mem(&m_core->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;
+}
+
+void adsp21062_device::generate_write_mode1_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 data)
+{
+ code_label skip;
+
+ // TODO: swap effects
+ if (data & 0x1)
+ fatalerror("generate_write_mode1_imm: tried to enable I8 bit reversing");
+ if (data & 0x2)
+ fatalerror("generate_write_mode1_imm: tried to enable I0 bit reversing");
+ if (data & 0x4)
+ fatalerror("generate_write_mode1_imm: tried to enable MR alternate");
+
+ // DAG1 regs 4-7
+ skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x8);
+ UML_JMPc(block, (data & 0x8) ? COND_NZ : COND_Z, skip); // don't swap if the bits are same
+ UML_CALLH(block, *m_swap_dag1_4_7);
+ UML_LABEL(block, skip);
+
+ // DAG1 regs 0-3
+ skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x10);
+ UML_JMPc(block, (data & 0x10) ? COND_NZ : COND_Z, skip); // don't swap if the bits are same
+ UML_CALLH(block, *m_swap_dag1_0_3);
+ UML_LABEL(block, skip);
+
+ // DAG2 regs 4-7
+ skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x20);
+ UML_JMPc(block, (data & 0x20) ? COND_NZ : COND_Z, skip); // don't swap if the bits are same
+ UML_CALLH(block, *m_swap_dag2_4_7);
+ UML_LABEL(block, skip);
+
+ // DAG2 regs 0-3
+ skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x40);
+ UML_JMPc(block, (data & 0x40) ? COND_NZ : COND_Z, skip); // don't swap if the bits are same
+ UML_CALLH(block, *m_swap_dag2_0_3);
+ UML_LABEL(block, skip);
+
+ // REG 8-15
+ skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x80);
+ UML_JMPc(block, (data & 0x80) ? COND_NZ : COND_Z, skip); // don't swap if the bits are same
+ UML_CALLH(block, *m_swap_r8_15);
+ UML_LABEL(block, skip);
+
+ // REG 0-7
+ skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x400);
+ UML_JMPc(block, (data & 0x400) ? COND_NZ : COND_Z, skip); // don't swap if the bits are same
+ UML_CALLH(block, *m_swap_r0_7);
+ UML_LABEL(block, skip);
+
+ UML_MOV(block, MODE1, data);
+}
+
+void adsp21062_device::generate_set_mode1_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 data)
+{
+ if (data & 0x1)
+ fatalerror("generate_set_mode1_imm: tried to enable I8 bit reversing");
+ if (data & 0x2)
+ fatalerror("generate_set_mode1_imm: tried to enable I0 bit reversing");
+ if (data & 0x4)
+ fatalerror("generate_set_mode1_imm: tried to enable MR alternate");
+ if (data & 0x8) // DAG1 regs 4-7
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x8);
+ UML_JMPc(block, COND_NZ, skip); // don't swap if the bit is already 1
+ UML_CALLH(block, *m_swap_dag1_4_7);
+ UML_LABEL(block, skip);
+ }
+ if (data & 0x10) // DAG1 regs 0-3
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x10);
+ UML_JMPc(block, COND_NZ, skip); // don't swap if the bit is already 1
+ UML_CALLH(block, *m_swap_dag1_0_3);
+ UML_LABEL(block, skip);
+ }
+ if (data & 0x20) // DAG2 regs 4-7
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x20);
+ UML_JMPc(block, COND_NZ, skip); // don't swap if the bit is already 1
+ UML_CALLH(block, *m_swap_dag2_4_7);
+ UML_LABEL(block, skip);
+ }
+ if (data & 0x40) // DAG1 regs 0-3
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x40);
+ UML_JMPc(block, COND_NZ, skip); // don't swap if the bit is already 1
+ UML_CALLH(block, *m_swap_dag2_0_3);
+ UML_LABEL(block, skip);
+ }
+ if (data & 0x80) // REG 8-15
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x80);
+ UML_JMPc(block, COND_NZ, skip); // don't swap if the bit is already 1
+ UML_CALLH(block, *m_swap_r8_15);
+ UML_LABEL(block, skip);
+ }
+ if (data & 0x400) // REG 0-7
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x400);
+ UML_JMPc(block, COND_NZ, skip); // don't swap if the bit is already 1
+ UML_CALLH(block, *m_swap_r0_7);
+ UML_LABEL(block, skip);
+ }
+
+ UML_OR(block, MODE1, MODE1, data);
+}
+
+void adsp21062_device::generate_clear_mode1_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 data)
+{
+ if (data & 0x1)
+ fatalerror("generate_clear_mode1_imm: tried to disable I8 bit reversing");
+ if (data & 0x2)
+ fatalerror("generate_clear_mode1_imm: tried to disable I0 bit reversing");
+ if (data & 0x4)
+ fatalerror("generate_clear_mode1_imm: tried to disable MR alternate");
+ if (data & 0x8) // DAG1 regs 4-7
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x8);
+ UML_JMPc(block, COND_Z, skip); // don't swap if the bit is already 0
+ UML_CALLH(block, *m_swap_dag1_4_7);
+ UML_LABEL(block, skip);
+ }
+ if (data & 0x10) // DAG1 regs 0-3
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x10);
+ UML_JMPc(block, COND_Z, skip); // don't swap if the bit is already 0
+ UML_CALLH(block, *m_swap_dag1_0_3);
+ UML_LABEL(block, skip);
+ }
+ if (data & 0x20) // DAG2 regs 4-7
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x20);
+ UML_JMPc(block, COND_Z, skip); // don't swap if the bit is already 0
+ UML_CALLH(block, *m_swap_dag2_4_7);
+ UML_LABEL(block, skip);
+ }
+ if (data & 0x40) // DAG1 regs 0-3
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x40);
+ UML_JMPc(block, COND_Z, skip); // don't swap if the bit is already 0
+ UML_CALLH(block, *m_swap_dag2_0_3);
+ UML_LABEL(block, skip);
+ }
+ if (data & 0x80) // REG 8-15
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x80);
+ UML_JMPc(block, COND_Z, skip); // don't swap if the bit is already 0
+ UML_CALLH(block, *m_swap_r8_15);
+ UML_LABEL(block, skip);
+ }
+ if (data & 0x400) // REG 0-7
+ {
+ code_label skip = compiler->labelnum++;
+ UML_TEST(block, MODE1, 0x400);
+ UML_JMPc(block, COND_Z, skip); // don't swap if the bit is already 0
+ UML_CALLH(block, *m_swap_r0_7);
+ UML_LABEL(block, skip);
+ }
+
+ UML_AND(block, MODE1, MODE1, ~data);
+}
+
+
+
+void adsp21062_device::generate_update_circular_buffer(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int g, int i)
+{
+ // TODO
+}
+
+void adsp21062_device::generate_astat_copy(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
+{
+ UML_MOV(block, mem(&m_core->astat_drc_copy.az), ASTAT_AZ);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.av), ASTAT_AV);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.an), ASTAT_AN);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.av), ASTAT_AV);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.as), ASTAT_AS);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.ai), ASTAT_AI);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.af), ASTAT_AF);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.mn), ASTAT_MN);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.mv), ASTAT_MV);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.mu), ASTAT_MU);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.mi), ASTAT_MI);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.sv), ASTAT_SV);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.sz), ASTAT_SZ);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.ss), ASTAT_SS);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.btf), ASTAT_BTF);
+ UML_MOV(block, mem(&m_core->astat_drc_copy.cacc), mem(&m_core->astat_drc.cacc));
+}
+
+
+
+void adsp21062_device::generate_call(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, bool delayslot)
+{
+ // I0 = target pc for dynamic branches
+
+ compiler_state compiler_temp = *compiler;
+
+ // save branch target
+ if (desc->targetpc == BRANCH_TARGET_DYNAMIC)
+ {
+ UML_MOV(block, mem(&m_core->jmpdest), I0); // mov [jmpdest],i0
+ }
+
+ // compile delay slots if needed
+ if (delayslot)
+ {
+ generate_sequence_instruction(block, &compiler_temp, desc->delay.first());
+ generate_sequence_instruction(block, &compiler_temp, desc->delay.last());
+ }
+
+ if (delayslot)
+ UML_MOV(block, I0, desc->pc + 3);
+ else
+ UML_MOV(block, I0, desc->pc + 1);
+ UML_CALLH(block, *m_push_pc);
+
+ // update cycles and hash jump
+ if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
+ {
+ generate_update_cycles(block, &compiler_temp, desc->targetpc, TRUE);
+ if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
+ UML_JMP(block, desc->targetpc | 0x80000000); // jmp targetpc | 0x80000000
+ else
+ UML_HASHJMP(block, 0, desc->targetpc, *m_nocode); // hashjmp 0,targetpc,nocode
+ }
+ else
+ {
+ generate_update_cycles(block, &compiler_temp, mem(&m_core->jmpdest), TRUE);
+ UML_HASHJMP(block, 0, mem(&m_core->jmpdest), *m_nocode); // hashjmp 0,jmpdest,nocode
+ }
+
+ // update compiler label
+ compiler->labelnum = compiler_temp.labelnum;
+
+ /* reset the mapvar to the current cycles and account for skipped slots */
+ compiler->cycles += desc->skipslots;
+ UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles); // mapvar CYCLES,compiler->cycles
+}
+
+void adsp21062_device::generate_jump(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, bool delayslot, bool loopabort, bool clearint)
+{
+ // I0 = target pc for dynamic branches
+
+ compiler_state compiler_temp = *compiler;
+
+ // save branch target
+ if (desc->targetpc == BRANCH_TARGET_DYNAMIC)
+ {
+ UML_MOV(block, mem(&m_core->jmpdest), I0); // mov [jmpdest],i0
+ }
+
+ // compile delay slots if needed
+ if (delayslot)
+ {
+ generate_sequence_instruction(block, &compiler_temp, desc->delay.first());
+ generate_sequence_instruction(block, &compiler_temp, desc->delay.last());
+ }
+
+ // update cycles and hash jump
+ if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
+ {
+ generate_update_cycles(block, &compiler_temp, desc->targetpc, TRUE);
+ if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
+ UML_JMP(block, desc->targetpc | 0x80000000); // jmp targetpc | 0x80000000
+ else
+ UML_HASHJMP(block, 0, desc->targetpc, *m_nocode); // hashjmp 0,targetpc,nocode
+ }
+ else
+ {
+ generate_update_cycles(block, &compiler_temp, mem(&m_core->jmpdest), TRUE);
+ UML_HASHJMP(block, 0, mem(&m_core->jmpdest), *m_nocode); // hashjmp 0,jmpdest,nocode
+ }
+
+ // update compiler label
+ compiler->labelnum = compiler_temp.labelnum;
+
+ /* reset the mapvar to the current cycles and account for skipped slots */
+ compiler->cycles += desc->skipslots;
+ UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles); // mapvar CYCLES,compiler->cycles
+}
+
+/*-------------------------------------------------
+generate_write_ureg - UREG is read into I0
+-------------------------------------------------*/
+
+void adsp21062_device::generate_read_ureg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int ureg, bool has_compute)
+{
+ // UREG is read into I0
+
+ switch (ureg)
+ {
+ // REG 0-15
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
+ case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
+ UML_MOV(block, I0, REG(ureg & 0xf));
+ break;
+ // I0-7
+ case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ UML_MOV(block, I0, mem(&m_core->dag1.i[ureg & 7]));
+ break;
+ // I8-15
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ UML_MOV(block, I0, mem(&m_core->dag2.i[ureg & 7]));
+ break;
+ // M0-7
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+ UML_MOV(block, I0, mem(&m_core->dag1.m[ureg & 7]));
+ break;
+ // M8-15
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+ UML_MOV(block, I0, mem(&m_core->dag2.m[ureg & 7]));
+ break;
+ // L0-7
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+ UML_MOV(block, I0, mem(&m_core->dag1.l[ureg & 7]));
+ break;
+ // L8-15
+ case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+ UML_MOV(block, I0, mem(&m_core->dag2.l[ureg & 7]));
+ break;
+ // B0-7
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ UML_MOV(block, I0, mem(&m_core->dag1.b[ureg & 7]));
+ break;
+ // B8-15
+ case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
+ UML_MOV(block, I0, mem(&m_core->dag2.b[ureg & 7]));
+ break;
+
+ case 0x64: // PCSTK
+ fatalerror("generate_read_ureg: PCSTK");
+ break;
+ case 0x70: // USTAT1
+ UML_MOV(block, I0, mem(&m_core->ustat1));
+ break;
+ case 0x71: // USTAT2
+ UML_MOV(block, I0, mem(&m_core->ustat2));
+ break;
+ case 0x79: // IRPTL
+ UML_MOV(block, I0, mem(&m_core->irptl));
+ break;
+ case 0x7a: // MODE2
+ UML_MOV(block, I0, mem(&m_core->mode2));
+ break;
+ case 0x7b: // MODE1
+ UML_MOV(block, I0, mem(&m_core->mode1));
+ break;
+ case 0x7c: // ASTAT
+ // construct from bits
+ if (!has_compute)
+ {
+ // no compute, just read normally from ASTAT
+ UML_XOR(block, I0, I0, I0);
+ UML_OR(block, I0, I0, ASTAT_AZ);
+ UML_SHL(block, I1, ASTAT_AV, 1);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_AN, 2);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_AC, 3);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_AS, 4);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_AI, 5);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_MN, 6);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_MV, 7);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_MU, 8);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_MI, 9);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_AF, 10);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_SV, 11);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_SZ, 12);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_SS, 13);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, ASTAT_BTF, 18);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, FLAG0, 19);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, FLAG1, 20);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, FLAG2, 21);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, FLAG3, 22);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc.cacc), 24);
+ UML_OR(block, I0, I0, I1);
+ }
+ else
+ {
+ // read from ASTAT copy if this opcode also does compute
+ UML_XOR(block, I0, I0, I0);
+ UML_OR(block, I0, I0, mem(&m_core->astat_drc_copy.az));
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.av), 1);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.an), 2);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.ac), 3);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.as), 4);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.ai), 5);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.mn), 6);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.mv), 7);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.mu), 8);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.mi), 9);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.af), 10);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.sv), 11);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.sz), 12);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.ss), 13);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.btf), 18);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, FLAG0, 19);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, FLAG1, 20);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, FLAG2, 21);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, FLAG3, 22);
+ UML_OR(block, I0, I0, I1);
+ UML_SHL(block, I1, mem(&m_core->astat_drc_copy.cacc), 24);
+ UML_OR(block, I0, I0, I1);
+ }
+ break;
+ case 0x7d: // IMASK
+ UML_MOV(block, I0, mem(&m_core->imask));
+ break;
+ case 0x7e: // STKY
+ UML_MOV(block, I0, mem(&m_core->stky));
+ break;
+ case 0xdb: // PX
+ UML_DMOV(block, I0, mem(&m_core->px)); // NOTE: this returns 64 bits
+ break;
+ case 0xdc: // PX1 (bits 0-15 of PX)
+ UML_MOV(block, I0, mem(&m_core->px));
+ UML_AND(block, I0, I0, 0xffff);
+ break;
+ case 0xdd: // PX2 (bits 16-47 of PX)
+ UML_DMOV(block, I0, mem(&m_core->px));
+ UML_DSHR(block, I0, I0, 16);
+ UML_DAND(block, I0, I0, 0xffffffff);
+ break;
+
+ default:
+ fatalerror("generate_read_ureg %02X", ureg);
+ break;
+ }
+}
+
+
+/*-------------------------------------------------
+ generate_write_ureg - contents of register I0 or 32-bit immediate data are written into UREG
+-------------------------------------------------*/
+
+void adsp21062_device::generate_write_ureg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int ureg, bool imm, UINT32 data)
+{
+ switch (ureg)
+ {
+ // REG 0-15
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
+ case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
+ UML_MOV(block, REG(ureg & 0xf), imm ? data : I0);
+ break;
+ // I0-7
+ case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ UML_MOV(block, DM_I(ureg & 7), imm ? data : I0);
+ break;
+ // I8-15
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ UML_MOV(block, PM_I(ureg & 7), imm ? data : I0);
+ break;
+ // M0-7
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+ UML_MOV(block, DM_M(ureg & 7), imm ? data : I0);
+ break;
+ // M8-15
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+ UML_MOV(block, PM_M(ureg & 7), imm ? data : I0);
+ break;
+ // L0-7
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+ UML_MOV(block, DM_L(ureg & 7), imm ? data : I0);
+ break;
+ // L8-15
+ case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+ UML_MOV(block, PM_L(ureg & 7), imm ? data : I0);
+ break;
+ // B0-7
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ // Note: loading B also loads the same value in I
+ UML_MOV(block, DM_B(ureg & 7), imm ? data : I0);
+ UML_MOV(block, DM_I(ureg & 7), imm ? data : I0);
+ break;
+ // B8-15
+ case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
+ // Note: loading B also loads the same value in I
+ UML_MOV(block, PM_B(ureg & 7), imm ? data : I0);
+ UML_MOV(block, PM_B(ureg & 7), imm ? data : I0);
+ break;
+
+ case 0x64: // PCSTK
+ fatalerror("generate_write_ureg: PCSTK");
+ break;
+ case 0x70: // USTAT1
+ UML_MOV(block, mem(&m_core->ustat1), imm ? data : I0);
+ break;
+ case 0x71: // USTAT2
+ UML_MOV(block, mem(&m_core->ustat2), imm ? data : I0);
+ break;
+ case 0x79: // IRPTL
+ UML_MOV(block, mem(&m_core->irptl), imm ? data : I0);
+ break;
+ case 0x7a: // MODE2
+ UML_MOV(block, mem(&m_core->mode2), imm ? data : I0);
+ break;
+ case 0x7b: // MODE1
+ // MODE1 needs to be written delayed
+ if (imm)
+ {
+ compiler->mode1_delay.counter = 2;
+ compiler->mode1_delay.data = data;
+ compiler->mode1_delay.mode = MODE1_WRITE_IMM;
+ }
+ else
+ {
+ compiler->mode1_delay.counter = 2;
+ compiler->mode1_delay.mode = MODE1_WRITE_REG;
+ UML_MOV(block, mem(&m_core->mode1_delay_data), I0);
+ }
+ break;
+ case 0x7c: // ASTAT
+ // TODO: needs bit break up
+ fatalerror("generate_write_ureg: ASTAT");
+ break;
+ case 0x7d: // IMASK
+ UML_MOV(block, mem(&m_core->imask), imm ? data : I0);
+ break;
+ case 0x7e: // STKY
+ UML_MOV(block, mem(&m_core->stky), imm ? data : I0);
+ break;
+ case 0xdb: // PX
+ if (imm)
+ {
+ fatalerror("generate_write_ureg %02X with immediate!", ureg);
+ }
+ else
+ {
+ UML_DMOV(block, mem(&m_core->px), I0);
+ }
+ break;
+ case 0xdc: // PX1 (bits 0-15 of PX)
+ if (imm)
+ {
+ UML_DAND(block, mem(&m_core->px), mem(&m_core->px), ~0xffff);
+ UML_DOR(block, mem(&m_core->px), mem(&m_core->px), (UINT64)(data));
+ }
+ else
+ {
+ UML_DAND(block, mem(&m_core->px), mem(&m_core->px), ~0xffff);
+ UML_DXOR(block, I1, I1, I1);
+ UML_DAND(block, I1, I0, 0xffff);
+ UML_DOR(block, mem(&m_core->px), mem(&m_core->px), I1);
+ }
+ break;
+ case 0xdd: // PX2 (bits 16-47 of PX)
+ if (imm)
+ {
+ UML_DAND(block, mem(&m_core->px), mem(&m_core->px), 0xffff);
+ UML_DOR(block, mem(&m_core->px), mem(&m_core->px), (UINT64)(data) << 16);
+ }
+ else
+ {
+ UML_DAND(block, mem(&m_core->px), mem(&m_core->px), 0xffff);
+ UML_DSHL(block, I0, I0, 16);
+ UML_DOR(block, mem(&m_core->px), mem(&m_core->px), I0);
+ }
+ break;
+
+ default:
+ fatalerror("generate_write_ureg %02X", ureg);
+ break;
+ }
+}
+
+int adsp21062_device::generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
+{
+ UINT64 opcode = desc->opptr.q[0];
+
+ switch ((opcode >> 45) & 7)
+ {
+ case 0: // subops
+ {
+ UINT32 subop = (opcode >> 40) & 0x1f;
+ switch (subop)
+ {
+ case 0x00: // NOP / idle |000|00000|
+ if (opcode & U64(0x008000000000))
+ {
+ // IDLE
+ UML_MOV(block, mem(&m_core->idle), 1);
+ UML_MOV(block, mem(&m_core->icount), 0);
+ return TRUE;
+ }
+ else
+ {
+ // NOP
+ return TRUE;
+ }
+ break;
+
+ case 0x01: // compute |000|00001|
+ {
+ int cond = (opcode >> 33) & 0x1f;
+
+ bool has_condition = !if_condition_always_true(cond);
+ int skip_label = 0;
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+
+ generate_compute(block, compiler, desc);
+
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+ return TRUE;
+ }
+
+ case 0x02: // immediate shift |000|00010|
+ {
+ int shiftop = (opcode >> 16) & 0x3f;
+ int rn = (opcode >> 4) & 0xf;
+ int rx = (opcode & 0xf);
+ int cond = (opcode >> 33) & 0x1f;
+ int data = ((opcode >> 8) & 0xff) | ((opcode >> 19) & 0xf00);
+
+ bool has_condition = !if_condition_always_true(cond);
+ int skip_label = 0;
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+
+ generate_shift_imm(block, compiler, desc, data, shiftop, rn, rx);
+
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+ return TRUE;
+ }
+
+ case 0x04: // compute / modify |000|00100|
+ {
+ int cond = (opcode >> 33) & 0x1f;
+ int compute = opcode & 0x7fffff;
+ int g = (opcode >> 38) & 0x1;
+ int m = (opcode >> 27) & 0x7;
+ int i = (opcode >> 30) & 0x7;
+
+ bool has_condition = !if_condition_always_true(cond);
+ int skip_label = 0;
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+
+ generate_compute(block, compiler, desc);
+
+ if (g)
+ {
+ // PM
+ UML_ADD(block, PM_I(i), PM_I(i), PM_M(m));
+ }
+ else
+ {
+ // DM
+ UML_ADD(block, DM_I(i), DM_I(i), DM_M(m));
+ }
+
+ generate_update_circular_buffer(block, compiler, desc, g, i);
+
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+
+ return TRUE;
+ }
+
+ case 0x06: // direct jump|call |000|00110|
+ {
+ int b = (opcode >> 39) & 0x1;
+ int j = (opcode >> 26) & 0x1;
+ int la = (opcode >> 38) & 0x1;
+ int ci = (opcode >> 24) & 0x1;
+ int cond = (opcode >> 33) & 0x1f;
+
+ bool has_condition = !if_condition_always_true(cond);
+ int skip_label = 0;
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+ if (b) // call
+ {
+ generate_call(block, compiler, desc, j != 0);
+ }
+ else // jump
+ {
+ generate_jump(block, compiler, desc, j != 0, la != 0, ci != 0);
+ }
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+ return TRUE;
+ }
+
+ case 0x07: // direct jump|call |000|00111|
+ {
+ int b = (opcode >> 39) & 0x1;
+ int j = (opcode >> 26) & 0x1;
+ int la = (opcode >> 38) & 0x1;
+ int ci = (opcode >> 24) & 0x1;
+ int cond = (opcode >> 33) & 0x1f;
+
+ bool has_condition = !if_condition_always_true(cond);
+ int skip_label = 0;
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+ if (b) // call
+ {
+ generate_call(block, compiler, desc, j != 0);
+ }
+ else // jump
+ {
+ generate_jump(block, compiler, desc, j != 0, la != 0, ci != 0);
+ }
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+ return TRUE;
+ }
+
+ case 0x08: // indirect jump|call / compute |000|01000|
+ {
+ int la = (opcode >> 38) & 0x1;
+ int ci = (opcode >> 24) & 0x1;
+ int b = (opcode >> 39) & 0x1;
+ int j = (opcode >> 26) & 0x1;
+ int e = (opcode >> 25) & 0x1;
+ int pmi = (opcode >> 30) & 0x7;
+ int pmm = (opcode >> 27) & 0x7;
+ int cond = (opcode >> 33) & 0x1f;
+ int compute = opcode & 0x7fffff;
+
+ if (e)
+ {
+ // IF ... ELSE
+
+ int label_else = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, label_else);
+
+ UML_ADD(block, I0, PM_I(pmi), PM_M(pmm));
+
+ if (b) // call
+ {
+ generate_call(block, compiler, desc, j != 0);
+ }
+ else // jump
+ {
+ generate_jump(block, compiler, desc, j != 0, la != 0, ci != 0);
+ }
+
+ UML_LABEL(block, label_else);
+ generate_compute(block, compiler, desc);
+ }
+ else
+ {
+ // IF
+ bool has_condition = !if_condition_always_true(cond);
+ int skip_label = 0;
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+ generate_compute(block, compiler, desc);
+
+ UML_ADD(block, I0, PM_I(pmi), PM_M(pmm));
+
+ if (b) // call
+ {
+ generate_call(block, compiler, desc, j != 0);
+ }
+ else // jump
+ {
+ generate_jump(block, compiler, desc, j != 0, la != 0, ci != 0);
+ }
+
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+ }
+
+ return TRUE;
+ }
+
+ case 0x09: // indirect jump|call / compute |000|01001|
+ {
+ int la = (opcode >> 38) & 0x1;
+ int ci = (opcode >> 24) & 0x1;
+ int b = (opcode >> 39) & 0x1;
+ int j = (opcode >> 26) & 0x1;
+ int e = (opcode >> 25) & 0x1;
+ int cond = (opcode >> 33) & 0x1f;
+ int compute = opcode & 0x7fffff;
+
+ if (e)
+ {
+ // IF ... ELSE
+
+ int label_else = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, label_else);
+
+ if (b) // call
+ {
+ generate_call(block, compiler, desc, j != 0);
+ }
+ else // jump
+ {
+ generate_jump(block, compiler, desc, j != 0, la != 0, ci != 0);
+ }
+
+ UML_LABEL(block, label_else);
+ generate_compute(block, compiler, desc);
+ }
+ else
+ {
+ // IF
+ bool has_condition = !if_condition_always_true(cond);
+ int skip_label = 0;
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+ generate_compute(block, compiler, desc);
+
+ if (b) // call
+ {
+ generate_call(block, compiler, desc, j != 0);
+ }
+ else // jump
+ {
+ generate_jump(block, compiler, desc, j != 0, la != 0, ci != 0);
+ }
+
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+ }
+
+ return TRUE;
+ }
+
+ case 0x0a: // return from subroutine / compute |000|01010|
+ {
+ int cond = (opcode >> 33) & 0x1f;
+ int j = (opcode >> 26) & 0x1;
+ int e = (opcode >> 25) & 0x1;
+ //int lr = (opcode >> 24) & 0x1;
+ int compute = opcode & 0x7fffff;
+
+ // TODO: loop re-entry
+
+ if (e)
+ {
+ // IF ... ELSE
+
+ int label_else = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, label_else);
+
+ UML_CALLH(block, *m_pop_pc);
+ generate_jump(block, compiler, desc, j != 0, false, false);
+
+ UML_LABEL(block, label_else);
+ generate_compute(block, compiler, desc);
+ }
+ else
+ {
+ // IF
+ bool has_condition = !if_condition_always_true(cond);
+ int skip_label = 0;
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+ generate_compute(block, compiler, desc);
+
+ UML_CALLH(block, *m_pop_pc);
+ generate_jump(block, compiler, desc, j != 0, false, false);
+
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+ }
+
+ return TRUE;
+ }
+
+ case 0x0b: // return from interrupt / compute |000|01011|
+ {
+ int cond = (opcode >> 33) & 0x1f;
+ int j = (opcode >> 26) & 0x1;
+ int e = (opcode >> 25) & 0x1;
+ int compute = opcode & 0x7fffff;
+
+
+ code_label skip_pop = compiler->labelnum++;
+
+ UML_MOV(block, mem(&m_core->interrupt_active), 0); // mov [interrupt_active],0
+ UML_MOV(block, I0, 1); // mov i0,1
+ UML_SHL(block, I0, I0, mem(&m_core->active_irq_num)); // shl i0,[active_irq_num]
+ UML_XOR(block, IRPTL, IRPTL, I0); // xor IRPTL,i0
+ UML_CMP(block, mem(&m_core->status_stkp), 0); // cmp [status_stkp],0
+ UML_JMPc(block, COND_Z, skip_pop); // jz skip_pop
+ UML_CALLH(block, *m_pop_status); // callh m_pop_status
+
+ UML_LABEL(block, skip_pop); // skip_pop:
+
+ // TODO: check interrupts
+
+ if (e)
+ {
+ // IF ... ELSE
+
+ code_label label_else = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, label_else);
+
+ UML_CALLH(block, *m_pop_pc);
+ generate_jump(block, compiler, desc, j != 0, false, false);
+
+ UML_LABEL(block, label_else);
+ generate_compute(block, compiler, desc);
+ }
+ else
+ {
+ // IF
+ bool has_condition = !if_condition_always_true(cond);
+ code_label skip_label = 0;
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+ generate_compute(block, compiler, desc);
+
+ UML_CALLH(block, *m_pop_pc);
+ generate_jump(block, compiler, desc, j != 0, false, false);
+
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+ }
+
+ return TRUE;
+ }
+
+ case 0x0c: // do until counter expired |000|01100|
+ {
+ UINT16 data = (UINT16)(opcode >> 24);
+ int offset = SIGN_EXTEND24(opcode & 0xffffff);
+ UINT32 address = desc->pc + offset;
+
+ UML_MOV(block, LCNTR, data);
+ if (data > 0)
+ {
+ // push pc
+ UML_MOV(block, I0, desc->pc + 1);
+ UML_CALLH(block, *m_push_pc);
+
+ // push loop
+ UML_MOV(block, I0, data);
+ UML_MOV(block, I1, address);
+ UML_CALLH(block, *m_push_loop);
+ }
+ return TRUE;
+ }
+
+ case 0x0d: // do until counter expired |000|01101|
+ {
+ int ureg = (opcode >> 32) & 0xff;
+ int offset = SIGN_EXTEND24(opcode & 0xffffff);
+ UINT32 address = desc->pc + offset;
+
+ generate_read_ureg(block, compiler, desc, ureg, false);
+
+ UML_AND(block, I3, I0, 0xffff);
+ UML_MOV(block, LCNTR, I3);
+
+ // push pc
+ UML_MOV(block, I0, desc->pc + 1);
+ UML_CALLH(block, *m_push_pc);
+
+ // push loop
+ UML_MOV(block, I0, I3);
+ UML_MOV(block, I1, address);
+ UML_CALLH(block, *m_push_loop);
+ return TRUE;
+ }
+
+ case 0x0e: // do until |000|01110|
+ {
+ int offset = SIGN_EXTEND24(opcode & 0xffffff);
+ UINT32 address = desc->pc + offset;
+
+ // push pc
+ UML_MOV(block, I0, desc->pc + 1);
+ UML_CALLH(block, *m_push_pc);
+
+ // push loop
+ UML_MOV(block, I0, 0);
+ UML_MOV(block, I1, address);
+ UML_CALLH(block, *m_push_loop);
+ return TRUE;
+ }
+
+ case 0x0f: // immediate data -> ureg |000|01111|
+ {
+ int ureg = (opcode >> 32) & 0xff;
+ UINT32 data = (UINT32)opcode;
+
+ generate_write_ureg(block, compiler, desc, ureg, true, data);
+ return TRUE;
+ }
+
+ case 0x10: // ureg <-> DM|PM (direct) |000|100|G|D|
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ {
+ int ureg = (opcode >> 32) & 0xff;
+ UINT32 address = (UINT32)(opcode);
+ int d = (opcode >> 40) & 1;
+ int g = (opcode >> 41) & 1;
+
+ UML_MOV(block, I1, address);
+ if (d)
+ {
+ generate_read_ureg(block, compiler, desc, ureg, false);
+
+ // write
+ if (g)
+ {
+ // PM
+ if (ureg == 0xdb) // PX is 48-bit
+ UML_CALLH(block, *m_pm_write48);
+ else
+ UML_CALLH(block, *m_pm_write32);
+ }
+ else
+ {
+ // DM
+ UML_CALLH(block, *m_dm_write32);
+ }
+ }
+ else
+ {
+ // read
+ if (g)
+ {
+ // PM
+ if (ureg == 0xdb) // PX is 48-bit
+ UML_CALLH(block, *m_pm_read48);
+ else
+ UML_CALLH(block, *m_pm_read32);
+ }
+ else
+ {
+ // DM
+ UML_CALLH(block, *m_dm_read32);
+ }
+
+ generate_write_ureg(block, compiler, desc, ureg, false, 0);
+ }
+ return TRUE;
+ }
+
+ case 0x14: // system register bit manipulation |000|10100|
+ {
+ int bop = (opcode >> 37) & 0x7;
+ int sreg = (opcode >> 32) & 0xf;
+ UINT32 data = (UINT32)opcode;
+
+ switch (bop)
+ {
+ case 0: // SET
+ {
+ switch (sreg)
+ {
+ case 0x0: // USTAT1
+ UML_OR(block, USTAT1, USTAT1, data);
+ break;
+ case 0x1: // USTAT2
+ UML_OR(block, USTAT2, USTAT2, data);
+ break;
+ case 0x9: // IRPTL
+ UML_OR(block, IRPTL, IRPTL, data);
+ break;
+ case 0xa: // MODE2
+ UML_OR(block, MODE2, MODE2, data);
+ break;
+ case 0xb: // MODE1
+ compiler->mode1_delay.counter = 2;
+ compiler->mode1_delay.data = data;
+ compiler->mode1_delay.mode = MODE1_SET;
+ break;
+ case 0xc: // ASTAT
+ return FALSE;
+ case 0xd: // IMASK
+ UML_OR(block, IMASK, IMASK, data);
+ break;
+ case 0xe: // STKY
+ UML_OR(block, STKY, STKY, data);
+ break;
+ case 0xf: // IMASKP
+ UML_OR(block, IMASKP, IMASKP, data);
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+ }
+ case 1: // CLEAR
+ {
+ switch (sreg)
+ {
+ case 0x0: // USTAT1
+ UML_AND(block, USTAT1, USTAT1, ~data);
+ break;
+ case 0x1: // USTAT2
+ UML_AND(block, USTAT2, USTAT2, ~data);
+ break;
+ case 0x9: // IRPTL
+ UML_AND(block, IRPTL, IRPTL, ~data);
+ break;
+ case 0xa: // MODE2
+ UML_AND(block, MODE2, MODE2, ~data);
+ break;
+ case 0xb: // MODE1
+ compiler->mode1_delay.counter = 2;
+ compiler->mode1_delay.data = data;
+ compiler->mode1_delay.mode = MODE1_CLEAR;
+ break;
+ case 0xc: // ASTAT
+ return FALSE;
+ case 0xd: // IMASK
+ UML_AND(block, IMASK, IMASK, ~data);
+ break;
+ case 0xe: // STKY
+ UML_AND(block, STKY, STKY, ~data);
+ break;
+ case 0xf: // IMASKP
+ UML_AND(block, IMASKP, IMASKP, ~data);
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+ }
+ case 2: // TOGGLE
+ {
+ switch (sreg)
+ {
+ case 0x0: // USTAT1
+ UML_XOR(block, USTAT1, USTAT1, data);
+ break;
+ case 0x1: // USTAT2
+ UML_XOR(block, USTAT2, USTAT2, data);
+ break;
+ case 0x9: // IRPTL
+ UML_XOR(block, IRPTL, IRPTL, data);
+ break;
+ case 0xa: // MODE2
+ UML_XOR(block, MODE2, MODE2, data);
+ break;
+ case 0xb: // MODE1
+ compiler->mode1_delay.counter = 2;
+ compiler->mode1_delay.data = data;
+ compiler->mode1_delay.mode = MODE1_TOGGLE;
+ break;
+ case 0xc: // ASTAT
+ return FALSE;
+ case 0xd: // IMASK
+ UML_XOR(block, IMASK, IMASK, data);
+ break;
+ case 0xe: // STKY
+ UML_XOR(block, STKY, STKY, data);
+ break;
+ case 0xf: // IMASKP
+ UML_XOR(block, IMASKP, IMASKP, data);
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+ }
+ case 4: // TEST
+ {
+ switch (sreg)
+ {
+ case 0x0: // USTAT1
+ UML_AND(block, I0, USTAT1, data);
+ UML_CMP(block, I0, data);
+ UML_SETc(block, COND_E, ASTAT_BTF);
+ break;
+ case 0x1: // USTAT2
+ UML_AND(block, I0, USTAT2, data);
+ UML_CMP(block, I0, data);
+ UML_SETc(block, COND_E, ASTAT_BTF);
+ break;
+ case 0x9: // IRPTL
+ UML_AND(block, I0, IRPTL, data);
+ UML_CMP(block, I0, data);
+ UML_SETc(block, COND_E, ASTAT_BTF);
+ break;
+ case 0xa: // MODE2
+ UML_AND(block, I0, MODE2, data);
+ UML_CMP(block, I0, data);
+ UML_SETc(block, COND_E, ASTAT_BTF);
+ break;
+ case 0xb: // MODE1
+ UML_AND(block, I0, MODE1, data);
+ UML_CMP(block, I0, data);
+ UML_SETc(block, COND_E, ASTAT_BTF);
+ break;
+ case 0xc: // ASTAT
+ return FALSE;
+ case 0xd: // IMASK
+ UML_AND(block, I0, IMASK, data);
+ UML_CMP(block, I0, data);
+ UML_SETc(block, COND_E, ASTAT_BTF);
+ break;
+ case 0xe: // STKY
+ UML_AND(block, I0, STKY, data);
+ UML_CMP(block, I0, data);
+ UML_SETc(block, COND_E, ASTAT_BTF);
+ break;
+ case 0xf: // IMASKP
+ UML_AND(block, I0, IMASKP, data);
+ UML_CMP(block, I0, data);
+ UML_SETc(block, COND_E, ASTAT_BTF);
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+ }
+ case 5: // XOR
+ {
+ return FALSE;
+ }
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ case 0x16: // I register modify / bit-reverse |000|10110|
+ {
+ if (opcode & U64(0x008000000000)) // bit reverse
+ {
+ return FALSE;
+ }
+ else // modify
+ {
+ int g = (opcode >> 38) & 0x1;
+ int i = (opcode >> 32) & 0x7;
+ INT32 data = (INT32)(opcode);
+
+ if (g)
+ {
+ // PM
+ UML_ADD(block, PM_I(i), PM_I(i), data);
+ }
+ else
+ {
+ // DM
+ UML_ADD(block, DM_I(i), DM_I(i), data);
+ }
+ generate_update_circular_buffer(block, compiler, desc, g, i);
+ return TRUE;
+ }
+ }
+
+ case 0x17: // push|pop stacks / flush cache |000|10111|
+ return FALSE;
+
+ case 0x18: // cjump |000|11000|
+ return FALSE;
+
+ case 0x19: // rframe |000|11001|
+ return FALSE;
+
+ default:
+ return FALSE;
+ }
+ break;
+ }
+
+ case 1: // compute / dreg <-> DM / dreg <-> PM |001|
+ {
+ return FALSE;
+ }
+
+ case 2: // compute / ureg <-> DM|PM, register modify |010|
+ {
+ int u = (opcode >> 44) & 0x1;
+ int i = (opcode >> 41) & 0x7;
+ int m = (opcode >> 38) & 0x7;
+ int cond = (opcode >> 33) & 0x1f;
+ int g = (opcode >> 32) & 0x1;
+ int d = (opcode >> 31) & 0x1;
+ int ureg = (opcode >> 23) & 0xff;
+ int compute = opcode & 0x7fffff;
+
+ bool ureg_is_dreg = (ureg >= 0 && ureg < 16);
+ bool has_condition = !if_condition_always_true(cond);
+ int skip_label = 0;
+
+ bool ureg_is_astat = (ureg == 0x7c);
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+
+ if (d)
+ {
+ // UREG -> DM|PM
+ bool temp_ureg = false;
+
+ // save UREG if compute writes to it
+ if (compute != 0 && ureg_is_dreg && desc->regout[0] & (1 << (ureg & 0xf)))
+ {
+ UML_MOV(block, mem(&m_core->dreg_temp), REG(ureg & 0xf));
+ temp_ureg = true;
+ }
+
+ // save a copy of ASTAT if we need to read it
+ if (ureg_is_astat)
+ generate_astat_copy(block, compiler, desc);
+
+ // compute
+ generate_compute(block, compiler, desc);
+
+ // transfer
+ UML_MOV(block, I1, (g) ? PM_I(i) : DM_I(i)); // mov i1,dm|pm[i]
+ if (u == 0) // pre-modify without update
+ UML_ADD(block, I1, I1, (g) ? PM_M(m) : DM_M(m)); // add i1,i1,dm|pm[m]
+ if (temp_ureg)
+ UML_MOV(block, I0, mem(&m_core->dreg_temp)); // mov i0,[m_core->dreg_temp]
+ else
+ generate_read_ureg(block, compiler, desc, ureg, ureg_is_astat);
+
+ if (ureg == 0xdb && (g)) // PX is 48-bit when writing to PM
+ UML_CALLH(block, *m_pm_write48); // callh pm_write48
+ else
+ UML_CALLH(block, (g) ? *m_pm_write32 : *m_dm_write32); // callh dm|pm_write32
+ }
+ else
+ {
+ // DM|PM -> UREG
+
+ // compute
+ generate_compute(block, compiler, desc);
+
+ // transfer
+ UML_MOV(block, I1, (g) ? PM_I(i) : DM_I(i)); // mov i1,dm|pm[i]
+ if (u == 0) // pre-modify without update
+ UML_ADD(block, I1, I1, (g) ? PM_M(m) : DM_M(m)); // add i1,i1,dm|pm[m]
+
+ if (ureg == 0xdb && (g)) // PX is 48-bit when reading from PM
+ UML_CALLH(block, *m_pm_read48); // callh pm_read48
+ else
+ UML_CALLH(block, (g) ? *m_pm_read32 : *m_dm_read32); // callh dm|pm_read32
+ generate_write_ureg(block, compiler, desc, ureg, false, 0);
+ }
+
+ if (u != 0) // post-modify with update
+ {
+ if (g)
+ UML_ADD(block, PM_I(i), PM_I(i), PM_M(m)); // add pm[i],pm[m]
+ else
+ UML_ADD(block, DM_I(i), DM_I(i), DM_M(m)); // add dm[i],dm[m]
+
+ generate_update_circular_buffer(block, compiler, desc, g, i);
+ }
+
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+
+ return TRUE;
+ }
+
+ case 3:
+ {
+ if (opcode & U64(0x100000000000)) // compute / ureg <-> ureg |011|1|
+ {
+ int src_ureg = (opcode >> 36) & 0xff;
+ int dst_ureg = (opcode >> 23) & 0xff;
+ int cond = (opcode >> 31) & 0x1f;
+ int compute = opcode & 0x7fffff;
+
+ bool has_condition = !if_condition_always_true(cond);
+ bool src_is_dreg = (src_ureg >= 0 && src_ureg < 16);
+ int skip_label = 0;
+
+ bool src_ureg_is_astat = (src_ureg == 0x7c);
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+
+ bool temp_ureg = false;
+ // save UREG if compute writes to it
+ if (compute != 0 && src_is_dreg && desc->regout[0] & (1 << (src_ureg & 0xf)))
+ {
+ UML_MOV(block, mem(&m_core->dreg_temp), REG(src_ureg & 0xf));
+ temp_ureg = true;
+ }
+
+ // save a copy of ASTAT if we need to read it
+ if (src_ureg_is_astat)
+ generate_astat_copy(block, compiler, desc);
+
+ generate_compute(block, compiler, desc);
+
+ if (temp_ureg)
+ {
+ UML_MOV(block, I0, mem(&m_core->dreg_temp));
+ }
+ else
+ {
+ generate_read_ureg(block, compiler, desc, src_ureg, src_ureg_is_astat);
+ }
+ generate_write_ureg(block, compiler, desc, dst_ureg, false, 0);
+
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+
+ return TRUE;
+ }
+ else // compute / dreg <-> DM|PM, immediate modify |011|0|
+ {
+ int cond = (opcode >> 33) & 0x1f;
+ int u = (opcode >> 38) & 0x1;
+ int d = (opcode >> 39) & 0x1;
+ int g = (opcode >> 40) & 0x1;
+ int dreg = (opcode >> 23) & 0xf;
+ int i = (opcode >> 41) & 0x7;
+ int mod = SIGN_EXTEND6((opcode >> 27) & 0x3f);
+ int compute = opcode & 0x7fffff;
+
+ bool has_condition = !if_condition_always_true(cond);
+ int skip_label = 0;
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+ if (d)
+ {
+ // DREG -> DM|PM
+ bool temp_dreg = false;
+
+ // save dreg if compute writes to it
+ if (compute != 0 && desc->regout[0] & (1 << dreg))
+ {
+ UML_MOV(block, mem(&m_core->dreg_temp), REG(dreg));
+ temp_dreg = true;
+ }
+ // compute
+ generate_compute(block, compiler, desc);
+
+ // transfer
+ UML_MOV(block, I1, (g) ? PM_I(i) : DM_I(i)); // mov i1,dm|pm[i]
+ if (u == 0) // pre-modify without update
+ UML_ADD(block, I1, I1, mod); // add i1,i1,mod
+ if (temp_dreg)
+ UML_MOV(block, I0, mem(&m_core->dreg_temp)); // mov i0,[m_core->dreg_temp]
+ else
+ UML_MOV(block, I0, REG(dreg)); // mov i0,reg[dreg]
+ UML_CALLH(block, (g) ? *m_pm_write32 : *m_dm_write32); // callh dm|pm_write32
+ }
+ else
+ {
+ // DM|PM -> DREG
+
+ // compute
+ generate_compute(block, compiler, desc);
+
+ // transfer
+ UML_MOV(block, I1, (g) ? PM_I(i) : DM_I(i)); // mov i1,dm|pm[i]
+ if (u == 0) // pre-modify without update
+ UML_ADD(block, I1, I1, mod); // add i1,i1,mod
+ UML_CALLH(block, (g) ? *m_pm_read32 : *m_dm_read32); // callh dm|pm_read32
+ UML_MOV(block, REG(dreg), I0); // mov reg[dreg],i0
+ }
+
+ if (u != 0) // post-modify with update
+ {
+ if (g)
+ UML_ADD(block, PM_I(i), PM_I(i), mod); // add pm[i],mod
+ else
+ UML_ADD(block, DM_I(i), DM_I(i), mod); // add dm[i],mod
+
+ generate_update_circular_buffer(block, compiler, desc, g, i);
+ }
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+
+ return TRUE;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ if (opcode & U64(0x100000000000)) // immediate data -> DM|PM |100|1|
+ {
+ return FALSE;
+ }
+ else // immediate shift / dreg <-> DM|PM |100|0|
+ {
+ int i = (opcode >> 41) & 0x7;
+ int m = (opcode >> 38) & 0x7;
+ int g = (opcode >> 32) & 0x1;
+ int d = (opcode >> 31) & 0x1;
+ int dreg = (opcode >> 23) & 0xf;
+ int cond = (opcode >> 33) & 0x1f;
+ int data = ((opcode >> 8) & 0xff) | ((opcode >> 19) & 0xf00);
+ int shiftop = (opcode >> 16) & 0x3f;
+ int rn = (opcode >> 4) & 0xf;
+ int rx = (opcode & 0xf);
+
+ bool has_condition = !if_condition_always_true(cond);
+ int skip_label = 0;
+
+ if (has_condition)
+ {
+ skip_label = compiler->labelnum++;
+ generate_if_condition(block, compiler, desc, cond, skip_label);
+ }
+ if (d)
+ {
+ // DREG -> DM|PM
+ bool temp_dreg = false;
+
+ // save dreg if shiftop writes to it
+ if (desc->regout[0] & (1 << dreg))
+ {
+ UML_MOV(block, mem(&m_core->dreg_temp), REG(dreg));
+ temp_dreg = true;
+ }
+ // shiftop
+ generate_shift_imm(block, compiler, desc, data, shiftop, rn, rx);
+
+ // transfer
+ UML_MOV(block, I1, (g) ? PM_I(i) : DM_I(i)); // mov i1,dm|pm[i]
+ if (temp_dreg)
+ UML_MOV(block, I0, mem(&m_core->dreg_temp)); // mov i0,[m_core->dreg_temp]
+ else
+ UML_MOV(block, I0, REG(dreg)); // mov i0,reg[dreg]
+ UML_CALLH(block, (g) ? *m_pm_write32 : *m_dm_write32); // callh dm|pm_write32
+ }
+ else
+ {
+ // DM|PM -> DREG
+
+ // shiftop
+ generate_shift_imm(block, compiler, desc, data, shiftop, rn, rx);
+
+ // transfer
+ UML_MOV(block, I1, (g) ? PM_I(i) : DM_I(i)); // mov i1,dm|pm[i]
+ UML_CALLH(block, (g) ? *m_pm_read32 : *m_dm_read32); // callh dm|pm_read32
+ UML_MOV(block, REG(dreg), I0); // mov reg[dreg],i0
+ }
+
+ // update I
+ if (g)
+ UML_ADD(block, PM_I(i), PM_I(i), PM_M(m));
+ else
+ UML_ADD(block, DM_I(i), DM_I(i), DM_M(m));
+
+ generate_update_circular_buffer(block, compiler, desc, g, i);
+
+ if (has_condition)
+ UML_LABEL(block, skip_label);
+
+ return TRUE;
+ }
+ break;
+ }
+
+ case 5: // ureg <-> DM|PM (indirect) |101|
+ {
+ int g = (opcode >> 44) & 1;
+ int d = (opcode >> 40) & 1;
+ int i = (opcode >> 41) & 0x7;
+ int ureg = (opcode >> 32) & 0xff;
+ UINT32 offset = (UINT32)opcode;
+
+ if (d)
+ {
+ // UREG -> DM|PM
+ UML_ADD(block, I1, (g) ? PM_I(i) : DM_I(i), offset); // add i1,dm|pm[i],offset
+
+ generate_read_ureg(block, compiler, desc, ureg, false);
+
+ if (ureg == 0xdb && (g)) // PX is 48-bit when writing to PM
+ UML_CALLH(block, *m_pm_write48); // callh pm_write48
+ else
+ UML_CALLH(block, (g) ? *m_pm_write32 : *m_dm_write32); // callh dm|pm_write32
+ }
+ else
+ {
+ // DM|PM -> UREG
+ UML_ADD(block, I1, (g) ? PM_I(i) : DM_I(i), offset); // add i1,dm|pm[i],offset
+
+ if (ureg == 0xdb && (g)) // PX is 48-bit when reading from PM
+ UML_CALLH(block, *m_pm_read48); // callh pm_read48
+ else
+ UML_CALLH(block, (g) ? *m_pm_read32 : *m_dm_read32); // callh dm|pm_read32
+
+ generate_write_ureg(block, compiler, desc, ureg, false, 0);
+ }
+ return TRUE;
+ }
+
+ case 6: // indirect jump / compute / dreg <-> DM |110|
+ {
+ return FALSE;
+ }
+
+ case 7: // indirect jump / compute / dreg <-> DM |111|
+ {
+ return FALSE;
+ }
+ }
+
+ return FALSE;
+}
+
+void adsp21062_device::generate_unimplemented_compute(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
+{
+ UML_MOV(block, mem(&m_core->pc), desc->pc);
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr.q[0]);
+ UML_CALLC(block, cfunc_unimplemented_compute, this);
+}
+
+void adsp21062_device::generate_compute(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
+{
+ UINT64 opcode = desc->opptr.q[0];
+ if ((opcode & 0x7fffff) == 0)
+ return;
+
+ int rs = (opcode >> 12) & 0xf;
+ int rn = (opcode >> 8) & 0xf;
+ int ra = rn;
+ int rx = (opcode >> 4) & 0xf;
+ int ry = (opcode >> 0) & 0xf;
+ int ps = (opcode >> 16) & 0xf;
+
+ if (opcode & 0x400000) // multi-function operation
+ {
+ UINT32 multiop = (opcode >> 16) & 0x3f;
+ int fm = rs;
+ int fa = rn;
+ int fxm = (opcode >> 6) & 0x3; // registers 0 - 3
+ int fym = ((opcode >> 4) & 0x3) + 4; // registers 4 - 7
+ int fxa = ((opcode >> 2) & 0x3) + 8; // registers 8 - 11
+ int fya = (opcode & 0x3) + 12; // registers 12 - 15
+
+ switch (multiop)
+ {
+ case 0x00: // Rn = MRxx
+ {
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+ }
+
+ case 0x01: // MRxx = Rn
+ {
+ int ai = rs;
+ switch (ai)
+ {
+ case 0x00: // MR0F
+ UML_DAND(block, MRF, MRF, U64(0xffffffff00000000));
+ UML_AND(block, I0, REG(rn), 0xffffffff);
+ UML_DOR(block, MRF, MRF, I0);
+ break;
+ case 0x01: // MR1F
+ UML_DAND(block, MRF, MRF, U64(0x00000000ffffffff));
+ UML_DSHL(block, I0, REG(rn), 32);
+ UML_DOR(block, MRF, MRF, I0);
+ break;
+ case 0x04: // MR0B
+ UML_DAND(block, MRB, MRB, U64(0xffffffff00000000));
+ UML_AND(block, I0, REG(rn), 0xffffffff);
+ UML_DOR(block, MRB, MRB, I0);
+ break;
+ case 0x05: // MR1B
+ UML_DAND(block, MRB, MRB, U64(0x00000000ffffffff));
+ UML_DSHL(block, I0, REG(rn), 32);
+ UML_DOR(block, MRB, MRB, I0);
+ break;
+
+ case 0x02: // MR2F
+ case 0x06: // MR2B
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+ }
+ return;
+ }
+
+ case 0x07: // Ra = Rx + Ry, Rs = Rx - Ry
+ case 0x0f: // Fa = Fx + Fy, Fs = Fx - Fy
+ case 0x04: // Rm = R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12
+ case 0x05: // Rm = R3-0 * R7-4 (SSFR), Ra = R11-8 - R15-12
+ case 0x06: // Rm = R3-0 * R7-4 (SSFR), Ra = (R11-8 + R15-12) / 2
+ case 0x08: // MRF = MRF + R3-0 * R7-4 (SSF), Ra = R11-8 + R15-12
+ case 0x09: // MRF = MRF + R3-0 * R7-4 (SSF), Ra = R11-8 - R15-12
+ case 0x0a: // MRF = MRF + R3-0 * R7-4 (SSF), Ra = (R11-8 + R15-12) / 2
+ case 0x0c: // Rm = MRF + R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12
+ case 0x0d: // Rm = MRF + R3-0 * R7-4 (SSFR), Ra = R11-8 - R15-12
+ case 0x0e: // Rm = MRF + R3-0 * R7-4 (SSFR), Ra = (R11-8 + R15-12) / 2
+ case 0x10: // MRF = MRF - R3-0 * R7-4 (SSF), Ra = R11-8 + R15-12
+ case 0x11: // MRF = MRF - R3-0 * R7-4 (SSF), Ra = R11-8 - R15-12
+ case 0x12: // MRF = MRF - R3-0 * R7-4 (SSF), Ra = (R11-8 + R15-12) / 2
+ case 0x14: // Rm = MRF - R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12
+ case 0x15: // Rm = MRF - R3-0 * R7-4 (SSFR), Ra = R11-8 - R15-12
+ case 0x16: // Rm = MRF - R3-0 * R7-4 (SSFR), Ra = (R11-8 + R15-12) / 2
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+
+ case 0x1c: // Fm = F3-0 * F7-4, Fa = (F11-8 + F15-12) / 2
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+
+ case 0x1d: // Fm = F3-0 * F7-4, Fa = ABS F11-8
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+ // Rm = R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12, Rs = R11-8 - R15-12
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+ case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+ // Fm = F3-0 * F7-4, Fa = F11-8 + F15-12, Fs = F11-8 - F15-12
+ // TODO: denormals
+ UML_FSCOPYI(block, F0, REG(fxm));
+ UML_FSCOPYI(block, F1, REG(fym));
+ UML_FSCOPYI(block, F2, REG(fxa));
+ UML_FSCOPYI(block, F3, REG(fya));
+ UML_FSMUL(block, F0, F0, F1);
+ UML_FSADD(block, F4, F2, F3);
+ UML_FSSUB(block, F5, F2, F3);
+
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F4, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F5, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, I0);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, I1);
+ if (AZ_CALC_REQUIRED) UML_OR(block, ASTAT_AZ, ASTAT_AZ, I0);
+ if (AN_CALC_REQUIRED) UML_OR(block, ASTAT_AN, ASTAT_AN, I1);
+
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+
+ if (MN_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (MN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_MN);
+ // TODO: MV, MU, MI flags
+
+ UML_ICOPYFS(block, REG(fm), F0);
+ UML_ICOPYFS(block, REG(fa), F4);
+ UML_ICOPYFS(block, REG(ps), F5);
+ return;
+
+ case 0x18: // Fm = F3-0 * F7-4, Fa = F11-8 + F15-12
+ // TODO: denormals
+ UML_FSCOPYI(block, F0, REG(fxm));
+ UML_FSCOPYI(block, F1, REG(fym));
+ UML_FSCOPYI(block, F2, REG(fxa));
+ UML_FSCOPYI(block, F3, REG(fya));
+ UML_FSMUL(block, F0, F0, F1);
+ UML_FSADD(block, F2, F2, F3);
+
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F2, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+
+ if (MN_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (MN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_MN);
+ // TODO: MV, MU, MI flags
+
+ UML_ICOPYFS(block, REG(fm), F0);
+ UML_ICOPYFS(block, REG(fa), F2);
+ return;
+
+ case 0x19: // Fm = F3-0 * F7-4, Fa = F11-8 - F15-12
+ // TODO: denormals
+ UML_FSCOPYI(block, F0, REG(fxm));
+ UML_FSCOPYI(block, F1, REG(fym));
+ UML_FSCOPYI(block, F2, REG(fxa));
+ UML_FSCOPYI(block, F3, REG(fya));
+ UML_FSMUL(block, F0, F0, F1);
+ UML_FSSUB(block, F2, F2, F3);
+
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F2, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+
+ if (MN_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (MN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_MN);
+ // TODO: MV, MU, MI flags
+
+ UML_ICOPYFS(block, REG(fm), F0);
+ UML_ICOPYFS(block, REG(fa), F2);
+ return;
+
+ case 0x1a: // Fm = F3-0 * F7-4, Fa = FLOAT F11-8 BY R15-12
+ {
+ code_label denormal = compiler->labelnum++;
+ code_label end = compiler->labelnum++;
+
+ // TODO: denormals
+ UML_FSCOPYI(block, F0, REG(fxm));
+ UML_FSCOPYI(block, F1, REG(fym));
+ UML_FSMUL(block, F0, F0, F1);
+
+ UML_FSFRINT(block, F2, REG(fxa), SIZE_DWORD);
+ UML_ICOPYFS(block, I1, F2);
+ UML_AND(block, I0, I1, 0x7f800000);
+ UML_AND(block, I1, I1, 0x807fffff);
+ UML_SHR(block, I0, I0, 23);
+ UML_SUB(block, I0, I0, 127);
+ UML_ADD(block, I0, I0, REG(fya));
+ UML_CMP(block, I0, -126);
+ UML_JMPc(block, COND_L, denormal);
+
+ UML_ADD(block, I0, I0, 127);
+ UML_AND(block, I0, I0, 0xff);
+ UML_SHL(block, I0, I0, 23);
+ UML_OR(block, I0, I0, I1);
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ UML_JMP(block, end);
+
+ UML_LABEL(block, denormal);
+ UML_AND(block, I0, I1, 0x80000000);
+ if (AZ_CALC_REQUIRED) UML_MOV(block, ASTAT_AZ, 1);
+ if (AN_CALC_REQUIRED) UML_MOV(block, ASTAT_AN, 0);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+
+ UML_LABEL(block, end);
+
+ if (MN_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (MN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_MN);
+ // TODO: MV, MU, MI flags
+
+ UML_ICOPYFS(block, REG(fm), F0);
+ UML_MOV(block, REG(fa), I0);
+ return;
+ }
+
+ case 0x1b: // Fm = F3-0 * F7-4, Fa = FIX F11-8 BY R15-12
+ {
+ code_label denormal = compiler->labelnum++;
+ code_label end = compiler->labelnum++;
+
+ // TODO: denormals
+ UML_FSCOPYI(block, F0, REG(fxm));
+ UML_FSCOPYI(block, F1, REG(fym));
+ UML_FSMUL(block, F0, F0, F1);
+
+ UML_MOV(block, I1, REG(fxa));
+ UML_AND(block, I0, I1, 0x7f800000);
+ UML_AND(block, I1, I1, 0x807fffff);
+ UML_SHR(block, I0, I0, 23);
+ UML_SUB(block, I0, I0, 127);
+ UML_ADD(block, I0, I0, REG(fya));
+ UML_CMP(block, I0, -126);
+ UML_JMPc(block, COND_L, denormal);
+
+ UML_ADD(block, I0, I0, 127);
+ UML_AND(block, I0, I0, 0xff);
+ UML_SHL(block, I0, I0, 23);
+ UML_OR(block, I0, I0, I1);
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ UML_JMP(block, end);
+
+ UML_LABEL(block, denormal);
+ UML_AND(block, I0, I1, 0x80000000);
+ if (AZ_CALC_REQUIRED) UML_MOV(block, ASTAT_AZ, 1);
+ if (AN_CALC_REQUIRED) UML_MOV(block, ASTAT_AN, 0);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+
+ UML_LABEL(block, end);
+
+ UML_FSCOPYI(block, F2, I0);
+ UML_TEST(block, MODE1, MODE1_TRUNCATE);
+ UML_JMPc(block, COND_Z, compiler->labelnum);
+ UML_FSTOINT(block, I0, F2, SIZE_DWORD, ROUND_TRUNC);
+ UML_JMP(block, compiler->labelnum + 1);
+ UML_LABEL(block, compiler->labelnum++);
+ UML_FSTOINT(block, I0, F2, SIZE_DWORD, ROUND_ROUND);
+ UML_LABEL(block, compiler->labelnum++);
+
+ if (MN_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (MN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_MN);
+ // TODO: MV, MU, MI flags
+
+ UML_ICOPYFS(block, REG(fm), F0);
+ UML_MOV(block, REG(fa), I0);
+ return;
+ }
+
+ case 0x1e: // Fm = F3-0 * F7-4, Fa = MAX(F11-8, F15-12)
+ // TODO: denormals
+ UML_FSCOPYI(block, F0, REG(fxm));
+ UML_FSCOPYI(block, F1, REG(fym));
+ UML_FSCOPYI(block, F2, REG(fxa));
+ UML_FSCOPYI(block, F3, REG(fya));
+ UML_FSMUL(block, F0, F0, F1);
+
+ UML_FSMOV(block, F4, F2);
+ UML_FSCMP(block, F2, F3);
+ UML_FSMOVc(block, COND_C, F4, F3);
+
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F4, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+
+ if (MN_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (MN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_MN);
+ // TODO: MV, MU, MI flags
+
+ UML_ICOPYFS(block, REG(fm), F0);
+ UML_ICOPYFS(block, REG(fa), F4);
+ return;
+
+ case 0x1f: // Fm = F3-0 * F7-4, Fa = MIN(F11-8, F15-12)
+ // TODO: denormals
+ UML_FSCOPYI(block, F0, REG(fxm));
+ UML_FSCOPYI(block, F1, REG(fym));
+ UML_FSCOPYI(block, F2, REG(fxa));
+ UML_FSCOPYI(block, F3, REG(fya));
+ UML_FSMUL(block, F0, F0, F1);
+
+ UML_FSMOV(block, F4, F2);
+ UML_FSCMP(block, F3, F2);
+ UML_FSMOVc(block, COND_C, F4, F3);
+
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F4, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+
+ if (MN_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (MN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_MN);
+ // TODO: MV, MU, MI flags
+
+ UML_ICOPYFS(block, REG(fm), F0);
+ UML_ICOPYFS(block, REG(fa), F4);
+ return;
+
+ default:
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+ }
+ }
+ else // single-function operation
+ {
+ UINT32 operation = (opcode >> 12) & 0xff;
+
+ switch ((opcode >> 20) & 3)
+ {
+ case 0: // ALU operations
+ {
+ switch (operation)
+ {
+ case 0x09: // Rn = (Rx + Ry) / 2
+ case 0x61: // Rn = MIN(Rx, Ry)
+ case 0x63: // Rn = CLIP Rx BY Ry
+ case 0x92: // Fn = ABS(Fx - Fy)
+ case 0x89: // Fn = (Fx + Fy) / 2
+ case 0xdd: // Rn = TRUNC Fx BY Ry
+ case 0xe3: // Fn = CLIP Fx BY Fy
+ case 0xe0: // Fn = Fx COPYSIGN Fy
+ case 0x05: // Rn = Rx + Ry + CI
+ case 0x06: // Rn = Rx - Ry + CI - 1
+ case 0x25: // Rn = Rx + CI
+ case 0x26: // Rn = Rx + CI - 1
+ case 0x30: // Rn = ABS Rx
+ case 0x43: // Rn = NOT Rx
+ case 0xb0: // Fn = ABS(Fx)
+ case 0xa5: // Fn = RND Fx
+ case 0xad: // Rn = MANT Fx
+ case 0xc9: // Rn = FIX Fx
+ case 0xcd: // Rn = TRUNC Fx
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+
+ case 0x01: // Rn = Rx + Ry
+ UML_ADD(block, REG(rn), REG(rx), REG(ry));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_SETc(block, COND_V, ASTAT_AV);
+ if (AC_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AC);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0x02: // Rn = Rx - Ry
+ UML_SUB(block, REG(rn), REG(rx), REG(ry));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_SETc(block, COND_V, ASTAT_AV);
+ if (AC_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AC);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0x0a: // COMP(Rx, Ry)
+ UML_CMP(block, REG(rx), REG(ry));
+ UML_SETc(block, COND_Z, I0);
+ UML_SETc(block, COND_L, I1);
+ UML_MOV(block, ASTAT_AZ, I0);
+ UML_MOV(block, ASTAT_AN, I1);
+ UML_XOR(block, I0, I0, 1);
+ UML_XOR(block, I1, I1, 1);
+ UML_AND(block, I0, I0, I1);
+ UML_SHL(block, I0, I0, 7);
+
+ UML_MOV(block, I2, mem(&m_core->astat_drc.cacc));
+ UML_SHR(block, I2, I2, 1);
+ UML_OR(block, I2, I2, I0);
+ UML_MOV(block, mem(&m_core->astat_drc.cacc), I2);
+
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0);
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0x21: // Rn = PASS Rx
+ UML_MOV(block, REG(rn), REG(rx));
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_CMP(block, REG(rn), 0);
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0);
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0x22: // Rn = -Rx
+ UML_SUB(block, REG(rn), 0, REG(rx));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_SETc(block, COND_V, ASTAT_AV);
+ if (AC_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AC);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0x29: // Rn = Rx + 1
+ UML_ADD(block, REG(rn), REG(rx), 1);
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_SETc(block, COND_V, ASTAT_AV);
+ if (AC_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AC);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0x2a: // Rn = Rx - 1
+ UML_SUB(block, REG(rn), REG(rx), 1);
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_SETc(block, COND_V, ASTAT_AV);
+ if (AC_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AC);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0x40: // Rn = Rx AND Ry
+ UML_AND(block, REG(rn), REG(rx), REG(ry));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0);
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0x41: // Rn = Rx OR Ry
+ UML_OR(block, REG(rn), REG(rx), REG(ry));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0);
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0x42: // Rn = Rx XOR Ry
+ UML_XOR(block, REG(rn), REG(rx), REG(ry));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0);
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0x62: // Rn = MAX(Rx, Ry)
+ UML_MOV(block, REG(rn), REG(rx));
+ UML_CMP(block, REG(rx), REG(ry));
+ UML_MOVc(block, COND_L, REG(rn), REG(ry));
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_CMP(block, REG(rn), 0);
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0);
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
+ case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
+ {
+ /* Fixed-point Dual Add/Subtract */
+ UML_ADD(block, I0, REG(rx), REG(ry));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_SETc(block, COND_V, ASTAT_AV);
+ if (AC_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AC);
+ UML_SUB(block, I1, REG(rx), REG(ry));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, mem(&m_core->arg0));
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, mem(&m_core->arg1));
+ if (AV_CALC_REQUIRED) UML_SETc(block, COND_V, mem(&m_core->arg2));
+ if (AC_CALC_REQUIRED) UML_SETc(block, COND_C, mem(&m_core->arg3));
+ if (AZ_CALC_REQUIRED) UML_OR(block, ASTAT_AZ, ASTAT_AZ, mem(&m_core->arg0));
+ if (AN_CALC_REQUIRED) UML_OR(block, ASTAT_AN, ASTAT_AN, mem(&m_core->arg1));
+ if (AV_CALC_REQUIRED) UML_OR(block, ASTAT_AV, ASTAT_AV, mem(&m_core->arg2));
+ if (AC_CALC_REQUIRED) UML_OR(block, ASTAT_AC, ASTAT_AC, mem(&m_core->arg3));
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ UML_MOV(block, REG(ra), I0);
+ UML_MOV(block, REG(rs), I1);
+ return;
+ }
+
+ case 0x81: // Fn = Fx + Fy
+ // TODO: denormals
+ UML_FSCOPYI(block, F0, REG(rx));
+ UML_FSCOPYI(block, F1, REG(ry));
+ UML_FSADD(block, F0, F0, F1);
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ UML_ICOPYFS(block, REG(rn), F0);
+ return;
+
+ case 0x82: // Fn = Fx - Fy
+ // TODO: denormals
+ UML_FSCOPYI(block, F0, REG(rx));
+ UML_FSCOPYI(block, F1, REG(ry));
+ UML_FSSUB(block, F0, F0, F1);
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ UML_ICOPYFS(block, REG(rn), F0);
+ return;
+
+ case 0x8a: // COMP(Fx, Fy)
+ UML_FSCOPYI(block, F0, REG(rx));
+ UML_FSCOPYI(block, F1, REG(ry));
+ UML_FSCMP(block, F0, F1);
+ UML_SETc(block, COND_Z, I0);
+ UML_SETc(block, COND_C, I1);
+ UML_MOV(block, ASTAT_AZ, I0);
+ UML_MOV(block, ASTAT_AN, I1);
+ UML_XOR(block, I0, I0, 1);
+ UML_XOR(block, I1, I1, 1);
+ UML_AND(block, I0, I0, I1);
+ UML_SHL(block, I0, I0, 7);
+
+ UML_MOV(block, I2, mem(&m_core->astat_drc.cacc));
+ UML_SHR(block, I2, I2, 1);
+ UML_OR(block, I2, I2, I0);
+ UML_MOV(block, mem(&m_core->astat_drc.cacc), I2);
+
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0);
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ return;
+
+ case 0x91: // Fn = ABS(Fx + Fy)
+ // TODO: denormals
+ UML_FSCOPYI(block, F0, REG(rx));
+ UML_FSCOPYI(block, F1, REG(ry));
+ UML_FSADD(block, F0, F0, F1);
+ UML_FSABS(block, F0, F0);
+ UML_ICOPYFS(block, REG(rn), F0);
+ if (AZ_CALC_REQUIRED) UML_MOV(block, ASTAT_AZ, 0); // TODO
+ if (AN_CALC_REQUIRED) UML_MOV(block, ASTAT_AN, 0);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ return;
+
+ case 0xa1: // Fn = PASS Fx
+ UML_MOV(block, REG(rn), REG(rx));
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ {
+ UML_FSCOPYI(block, F0, REG(rn));
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ }
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0);
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ return;
+
+ case 0xa2: // Fn = -Fx
+ UML_FSCOPYI(block, F0, REG(rx));
+ UML_FSNEG(block, F0, F0);
+ UML_ICOPYFS(block, REG(rn), F0);
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0);
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ return;
+
+ case 0xbd: // Fn = SCALB Fx BY Ry
+ // TODO: source = nan, result = denormal
+ UML_MOV(block, I1, REG(rx));
+ UML_AND(block, I0, I1, 0x7f800000);
+ UML_AND(block, I1, I1, 0x807fffff);
+ UML_SHR(block, I0, I0, 23);
+ UML_SUB(block, I0, I0, 127);
+ UML_ADD(block, I0, I0, REG(ry));
+ UML_ADD(block, I0, I0, 127);
+ UML_AND(block, I0, I0, 0xff);
+ UML_SHL(block, I0, I0, 23);
+ UML_OR(block, REG(rn), I0, I1);
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ return;
+
+ case 0xc1: // Rn = LOGB Fx
+ // TODO: source = zero, infinity, nan
+ UML_SHR(block, I0, REG(rx), 23);
+ UML_AND(block, I0, I0, 0xff);
+ UML_SUB(block, REG(rn), I0, 127);
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0xc4: // Fn = RECIPS Fx
+ // TODO: denormals
+ // TODO: use the bit accurate method from interpreter?
+ UML_FSCOPYI(block, F0, REG(rx));
+ if (AN_CALC_REQUIRED || AV_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AV);
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ UML_JMPc(block, COND_Z, compiler->labelnum);
+ UML_FSRECIP(block, F0, F0);
+ UML_LABEL(block, compiler->labelnum++);
+ if (AZ_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ UML_ICOPYFS(block, REG(rn), F0);
+ return;
+
+ case 0xc5: // Fn = RSQRTS Fx
+ // TODO: denormals
+ // TODO: use the bit accurate method from interpreter?
+ UML_FSCOPYI(block, F0, REG(rx));
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ UML_JMPc(block, COND_Z, compiler->labelnum);
+ UML_FSRSQRT(block, F0, F0);
+ UML_LABEL(block, compiler->labelnum++);
+ UML_ICOPYFS(block, REG(rn), F0);
+ // TODO: flags!
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ return;
+
+ case 0xca: // Fn = FLOAT Rx
+ UML_FSFRINT(block, F0, REG(rx), SIZE_DWORD);
+ UML_ICOPYFS(block, REG(rn), F0);
+ if (AZ_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ return;
+
+ case 0xd9: // Rn = FIX Fx BY Ry
+ {
+ code_label denormal = compiler->labelnum++;
+ code_label end = compiler->labelnum++;
+
+ UML_MOV(block, I1, REG(rx));
+ UML_AND(block, I0, I1, 0x7f800000);
+ UML_AND(block, I1, I1, 0x807fffff);
+ UML_SHR(block, I0, I0, 23);
+ UML_SUB(block, I0, I0, 127);
+ UML_ADD(block, I0, I0, REG(ry));
+ UML_CMP(block, I0, -126);
+ UML_JMPc(block, COND_L, denormal);
+
+ UML_ADD(block, I0, I0, 127);
+ UML_AND(block, I0, I0, 0xff);
+ UML_SHL(block, I0, I0, 23);
+ UML_OR(block, I0, I0, I1);
+
+ UML_FSCOPYI(block, F2, I0);
+ UML_TEST(block, MODE1, MODE1_TRUNCATE);
+ UML_JMPc(block, COND_Z, compiler->labelnum);
+ UML_FSTOINT(block, I0, F2, SIZE_DWORD, ROUND_TRUNC);
+ UML_JMP(block, compiler->labelnum + 1);
+ UML_LABEL(block, compiler->labelnum++);
+ UML_FSTOINT(block, I0, F2, SIZE_DWORD, ROUND_ROUND);
+ UML_LABEL(block, compiler->labelnum++);
+
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_CMP(block, I0, 0);
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ UML_MOV(block, REG(rn), I0);
+ UML_JMP(block, end);
+
+ UML_LABEL(block, denormal);
+ UML_AND(block, I0, I1, 0x80000000);
+ if (AZ_CALC_REQUIRED) UML_MOV(block, ASTAT_AZ, 1);
+ if (AN_CALC_REQUIRED) UML_MOV(block, ASTAT_AN, 0);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ UML_MOV(block, REG(rn), I0);
+
+ UML_LABEL(block, end);
+ return;
+ }
+
+ case 0xda: // Fn = FLOAT Rx BY Ry
+ {
+ code_label denormal = compiler->labelnum++;
+ code_label end = compiler->labelnum++;
+ UML_FSFRINT(block, F0, REG(rx), SIZE_DWORD);
+ UML_ICOPYFS(block, I1, F0);
+ UML_AND(block, I0, I1, 0x7f800000);
+ UML_AND(block, I1, I1, 0x807fffff);
+ UML_SHR(block, I0, I0, 23);
+ UML_SUB(block, I0, I0, 127);
+ UML_ADD(block, I0, I0, REG(ry));
+ UML_CMP(block, I0, -126);
+ UML_JMPc(block, COND_L, denormal);
+
+ UML_ADD(block, I0, I0, 127);
+ UML_AND(block, I0, I0, 0xff);
+ UML_SHL(block, I0, I0, 23);
+ UML_OR(block, REG(rn), I0, I1);
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_S, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ UML_JMP(block, end);
+
+ UML_LABEL(block, denormal);
+ UML_AND(block, I0, I1, 0x80000000);
+ if (AZ_CALC_REQUIRED) UML_MOV(block, ASTAT_AZ, 1);
+ if (AN_CALC_REQUIRED) UML_MOV(block, ASTAT_AN, 0);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0);
+ UML_MOV(block, REG(rn), I0);
+
+ UML_LABEL(block, end);
+ return;
+ }
+
+ case 0xe1: // Fn = MIN(Fx, Fy)
+ UML_FSCOPYI(block, F2, REG(rx));
+ UML_FSCOPYI(block, F3, REG(ry));
+ UML_FSMOV(block, F4, F2);
+ UML_FSCMP(block, F3, F2);
+ UML_FSMOVc(block, COND_C, F4, F3);
+
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F4, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ UML_ICOPYFS(block, REG(rn), F4);
+ return;
+
+ case 0xe2: // Fn = MAX(Fx, Fy)
+ UML_FSCOPYI(block, F2, REG(rx));
+ UML_FSCOPYI(block, F3, REG(ry));
+ UML_FSMOV(block, F4, F2);
+ UML_FSCMP(block, F2, F3);
+ UML_FSMOVc(block, COND_C, F4, F3);
+
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F4, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ UML_ICOPYFS(block, REG(rn), F4);
+ return;
+
+ case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
+ case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
+ {
+ /* Floating-point Dual Add/Subtract */
+ UML_FSCOPYI(block, F0, REG(rx));
+ UML_FSCOPYI(block, F1, REG(ry));
+ UML_FSADD(block, F2, F0, F1);
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F2, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_AZ);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_AN);
+ UML_FSSUB(block, F3, F0, F1);
+ if (AZ_CALC_REQUIRED || AN_CALC_REQUIRED)
+ UML_FSCMP(block, F2, mem(&m_core->fp0));
+ if (AZ_CALC_REQUIRED) UML_SETc(block, COND_Z, I0);
+ if (AN_CALC_REQUIRED) UML_SETc(block, COND_C, I1);
+ if (AZ_CALC_REQUIRED) UML_OR(block, ASTAT_AZ, ASTAT_AZ, I0);
+ if (AN_CALC_REQUIRED) UML_OR(block, ASTAT_AN, ASTAT_AN, I1);
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, 0); // TODO
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, 0);
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, 0);
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, 0); // TODO
+ UML_ICOPYFS(block, REG(ra), F2);
+ UML_ICOPYFS(block, REG(rs), F3);
+ return;
+ }
+
+ default:
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+ }
+ break;
+ }
+
+ case 1: // multiplier operations
+ {
+ switch (operation)
+ {
+ case 0x48: // Rn = Rx * Ry (UUF)
+ case 0x49: // Rn = Rx * Ry (UUFR)
+ case 0x50: // Rn = Rx * Ry (SUI)
+ case 0x58: // Rn = Rx * Ry (SUF)
+ case 0x59: // Rn = Rx * Ry (SUFR)
+ case 0x60: // Rn = Rx * Ry (USI)
+ case 0x68: // Rn = Rx * Ry (USF)
+ case 0x69: // Rn = Rx * Ry (USFR)
+ case 0x70: // Rn = Rx * Ry (SSI)
+ case 0x78: // Rn = Rx * Ry (SSF)
+ case 0x79: // Rn = Rx * Ry (SSFR)
+ case 0x44: // MRF = Rx * Ry (UUI)
+ case 0x4c: // MRF = Rx * Ry (UUF)
+ case 0x4d: // MRF = Rx * Ry (UUFR)
+ case 0x54: // MRF = Rx * Ry (SUI)
+ case 0x5c: // MRF = Rx * Ry (SUF)
+ case 0x5d: // MRF = Rx * Ry (SUFR)
+ case 0x64: // MRF = Rx * Ry (USI)
+ case 0x6c: // MRF = Rx * Ry (USF)
+ case 0x6d: // MRF = Rx * Ry (USFR)
+ case 0x74: // MRF = Rx * Ry (SSI)
+ case 0x7c: // MRF = Rx * Ry (SSF)
+ case 0x7d: // MRF = Rx * Ry (SSFR)
+ case 0x46: // MRB = Rx * Ry (UUI)
+ case 0x4e: // MRB = Rx * Ry (UUF)
+ case 0x4f: // MRB = Rx * Ry (UUFR)
+ case 0x56: // MRB = Rx * Ry (SUI)
+ case 0x5e: // MRB = Rx * Ry (SUF)
+ case 0x5f: // MRB = Rx * Ry (SUFR)
+ case 0x66: // MRB = Rx * Ry (USI)
+ case 0x6e: // MRB = Rx * Ry (USF)
+ case 0x6f: // MRB = Rx * Ry (USFR)
+ case 0x76: // MRB = Rx * Ry (SSI)
+ case 0x7e: // MRB = Rx * Ry (SSF)
+ case 0x7f: // MRB = Rx * Ry (SSFR)
+ case 0x80: // Rn = MRF + Rx * Ry (UUI)
+ case 0x88: // Rn = MRF + Rx * Ry (UUF)
+ case 0x89: // Rn = MRF + Rx * Ry (UUFR)
+ case 0x90: // Rn = MRF + Rx * Ry (SUI)
+ case 0x98: // Rn = MRF + Rx * Ry (SUF)
+ case 0x99: // Rn = MRF + Rx * Ry (SUFR)
+ case 0xa0: // Rn = MRF + Rx * Ry (USI)
+ case 0xa8: // Rn = MRF + Rx * Ry (USF)
+ case 0xa9: // Rn = MRF + Rx * Ry (USFR)
+ case 0xb8: // Rn = MRF + Rx * Ry (SSF)
+ case 0xb9: // Rn = MRF + Rx * Ry (SSFR)
+ case 0x82: // Rn = MRB + Rx * Ry (UUI)
+ case 0x8a: // Rn = MRB + Rx * Ry (UUF)
+ case 0x8b: // Rn = MRB + Rx * Ry (UUFR)
+ case 0x92: // Rn = MRB + Rx * Ry (SUI)
+ case 0x9a: // Rn = MRB + Rx * Ry (SUF)
+ case 0x9b: // Rn = MRB + Rx * Ry (SUFR)
+ case 0xa2: // Rn = MRB + Rx * Ry (USI)
+ case 0xaa: // Rn = MRB + Rx * Ry (USF)
+ case 0xab: // Rn = MRB + Rx * Ry (USFR)
+ case 0xba: // Rn = MRB + Rx * Ry (SSF)
+ case 0xbb: // Rn = MRB + Rx * Ry (SSFR)
+ case 0x84: // MRF = MRF + Rx * Ry (UUI)
+ case 0x8c: // MRF = MRF + Rx * Ry (UUF)
+ case 0x8d: // MRF = MRF + Rx * Ry (UUFR)
+ case 0x94: // MRF = MRF + Rx * Ry (SUI)
+ case 0x9c: // MRF = MRF + Rx * Ry (SUF)
+ case 0x9d: // MRF = MRF + Rx * Ry (SUFR)
+ case 0xa4: // MRF = MRF + Rx * Ry (USI)
+ case 0xac: // MRF = MRF + Rx * Ry (USF)
+ case 0xad: // MRF = MRF + Rx * Ry (USFR)
+ case 0xb4: // MRF = MRF + Rx * Ry (SSI)
+ case 0xbc: // MRF = MRF + Rx * Ry (SSF)
+ case 0xbd: // MRF = MRF + Rx * Ry (SSFR)
+ case 0x86: // MRB = MRB + Rx * Ry (UUI)
+ case 0x8e: // MRB = MRB + Rx * Ry (UUF)
+ case 0x8f: // MRB = MRB + Rx * Ry (UUFR)
+ case 0x96: // MRB = MRB + Rx * Ry (SUI)
+ case 0x9e: // MRB = MRB + Rx * Ry (SUF)
+ case 0x9f: // MRB = MRB + Rx * Ry (SUFR)
+ case 0xa6: // MRB = MRB + Rx * Ry (USI)
+ case 0xae: // MRB = MRB + Rx * Ry (USF)
+ case 0xaf: // MRB = MRB + Rx * Ry (USFR)
+ case 0xb6: // MRB = MRB + Rx * Ry (SSI)
+ case 0xbe: // MRB = MRB + Rx * Ry (SSF)
+ case 0xbf: // MRB = MRB + Rx * Ry (SSFR)
+ case 0xc0: // Rn = MRF - Rx * Ry (UUI)
+ case 0xc8: // Rn = MRF - Rx * Ry (UUF)
+ case 0xc9: // Rn = MRF - Rx * Ry (UUFR)
+ case 0xd0: // Rn = MRF - Rx * Ry (SUI)
+ case 0xd8: // Rn = MRF - Rx * Ry (SUF)
+ case 0xd9: // Rn = MRF - Rx * Ry (SUFR)
+ case 0xe0: // Rn = MRF - Rx * Ry (USI)
+ case 0xe8: // Rn = MRF - Rx * Ry (USF)
+ case 0xe9: // Rn = MRF - Rx * Ry (USFR)
+ case 0xf0: // Rn = MRF - Rx * Ry (SSI)
+ case 0xf8: // Rn = MRF - Rx * Ry (SSF)
+ case 0xf9: // Rn = MRF - Rx * Ry (SSFR)
+ case 0xc2: // Rn = MRB - Rx * Ry (UUI)
+ case 0xca: // Rn = MRB - Rx * Ry (UUF)
+ case 0xcb: // Rn = MRB - Rx * Ry (UUFR)
+ case 0xd2: // Rn = MRB - Rx * Ry (SUI)
+ case 0xda: // Rn = MRB - Rx * Ry (SUF)
+ case 0xdb: // Rn = MRB - Rx * Ry (SUFR)
+ case 0xe2: // Rn = MRB - Rx * Ry (USI)
+ case 0xea: // Rn = MRB - Rx * Ry (USF)
+ case 0xeb: // Rn = MRB - Rx * Ry (USFR)
+ case 0xf2: // Rn = MRB - Rx * Ry (SSI)
+ case 0xfa: // Rn = MRB - Rx * Ry (SSF)
+ case 0xfb: // Rn = MRB - Rx * Ry (SSFR)
+ case 0xc4: // MRF = MRF - Rx * Ry (UUI)
+ case 0xcc: // MRF = MRF - Rx * Ry (UUF)
+ case 0xcd: // MRF = MRF - Rx * Ry (UUFR)
+ case 0xd4: // MRF = MRF - Rx * Ry (SUI)
+ case 0xdc: // MRF = MRF - Rx * Ry (SUF)
+ case 0xdd: // MRF = MRF - Rx * Ry (SUFR)
+ case 0xe4: // MRF = MRF - Rx * Ry (USI)
+ case 0xec: // MRF = MRF - Rx * Ry (USF)
+ case 0xed: // MRF = MRF - Rx * Ry (USFR)
+ case 0xf4: // MRF = MRF - Rx * Ry (SSI)
+ case 0xfc: // MRF = MRF - Rx * Ry (SSF)
+ case 0xfd: // MRF = MRF - Rx * Ry (SSFR)
+ case 0xc6: // MRB = MRB - Rx * Ry (UUI)
+ case 0xce: // MRB = MRB - Rx * Ry (UUF)
+ case 0xcf: // MRB = MRB - Rx * Ry (UUFR)
+ case 0xd6: // MRB = MRB - Rx * Ry (SUI)
+ case 0xde: // MRB = MRB - Rx * Ry (SUF)
+ case 0xdf: // MRB = MRB - Rx * Ry (SUFR)
+ case 0xe6: // MRB = MRB - Rx * Ry (USI)
+ case 0xee: // MRB = MRB - Rx * Ry (USF)
+ case 0xef: // MRB = MRB - Rx * Ry (USFR)
+ case 0xf6: // MRB = MRB - Rx * Ry (SSI)
+ case 0xfe: // MRB = MRB - Rx * Ry (SSF)
+ case 0xff: // MRB = MRB - Rx * Ry (SSFR)
+ case 0x00: // Rn = SAT MRF (UI)
+ case 0x01: // Rn = SAT MRF (SI)
+ case 0x08: // Rn = SAT MRF (UF)
+ case 0x09: // Rn = SAT MRF (SF)
+ case 0x02: // Rn = SAT MRB (UI)
+ case 0x03: // Rn = SAT MRB (SI)
+ case 0x0a: // Rn = SAT MRB (UF)
+ case 0x0b: // Rn = SAT MRB (SF)
+ case 0x04: // MRF = SAT MRF (UI)
+ case 0x05: // MRF = SAT MRF (SI)
+ case 0x0c: // MRF = SAT MRF (UF)
+ case 0x0d: // MRF = SAT MRF (SF)
+ case 0x06: // MRB = SAT MRB (UI)
+ case 0x07: // MRB = SAT MRB (SI)
+ case 0x0e: // MRB = SAT MRB (UF)
+ case 0x0f: // MRB = SAT MRB (SF)
+ case 0x18: // Rn = RND MRF (U)
+ case 0x19: // Rn = RND MRF (S)
+ case 0x1a: // Rn = RND MRB (U)
+ case 0x1b: // Rn = RND MRB (S)
+ case 0x1c: // MRF = RND MRF (U)
+ case 0x1d: // MRF = RND MRF (S)
+ case 0x1e: // MRB = RND MRB (U)
+ case 0x1f: // MRB = RND MRB (S)
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+
+ case 0x14: // MRF = 0
+ UML_DMOV(block, mem(&m_core->mrf), 0);
+ if (MN_CALC_REQUIRED) UML_MOV(block, ASTAT_MN, 0);
+ if (MV_CALC_REQUIRED) UML_MOV(block, ASTAT_MV, 0);
+ if (MU_CALC_REQUIRED) UML_MOV(block, ASTAT_MU, 0);
+ if (MI_CALC_REQUIRED) UML_MOV(block, ASTAT_MI, 0);
+ return;
+
+ case 0x16: // MRB = 0
+ UML_DMOV(block, mem(&m_core->mrb), 0);
+ if (MN_CALC_REQUIRED) UML_MOV(block, ASTAT_MN, 0);
+ if (MV_CALC_REQUIRED) UML_MOV(block, ASTAT_MV, 0);
+ if (MU_CALC_REQUIRED) UML_MOV(block, ASTAT_MU, 0);
+ if (MI_CALC_REQUIRED) UML_MOV(block, ASTAT_MI, 0);
+ return;
+
+ case 0x30: // Fn = Fx * Fy
+ UML_FSCOPYI(block, F0, REG(rx));
+ UML_FSCOPYI(block, F1, REG(ry));
+ UML_FSMUL(block, F0, F0, F1);
+ UML_ICOPYFS(block, REG(rn), F0);
+ if (MN_CALC_REQUIRED)
+ UML_FSCMP(block, F0, mem(&m_core->fp0));
+ if (MN_CALC_REQUIRED) UML_SETc(block, COND_C, ASTAT_MN);
+ // TODO: MV, MU, MI flags
+ return;
+
+ case 0x40: // Rn = Rx * Ry (UUI)
+ UML_MULU(block, I0, I0, REG(rx), REG(ry));
+ UML_MOV(block, REG(rn), I0);
+ // TODO: flags
+ return;
+
+ case 0xb0: // Rn = MRF + Rx * Ry (SSI)
+ UML_DSEXT(block, I0, REG(rx), SIZE_DWORD);
+ UML_DSEXT(block, I1, REG(ry), SIZE_DWORD);
+ UML_DMULS(block, I0, I0, I0, I1);
+ UML_DADD(block, I0, I0, mem(&m_core->mrf));
+ UML_MOV(block, REG(rn), I0);
+ // TODO: flags!
+ return;
+
+ case 0xb2: // Rn = MRB + Rx * Ry (SSI)
+ UML_DSEXT(block, I0, REG(rx), SIZE_DWORD);
+ UML_DSEXT(block, I1, REG(ry), SIZE_DWORD);
+ UML_DMULS(block, I0, I0, I0, I1);
+ UML_DADD(block, I0, I0, mem(&m_core->mrb));
+ UML_MOV(block, REG(rn), I0);
+ // TODO: flags!
+ return;
+
+ default:
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+ }
+ break;
+ }
+
+ case 2: // shifter operations
+ {
+ switch (operation)
+ {
+ case 0x00: // Rn = LSHIFT Rx BY Ry | <data8>
+ case 0x04: // Rn = ASHIFT Rx BY Ry | <data8>
+ case 0xc4: // Rn = BCLR Rx BY Ry | <data8>
+ case 0x44: // Rn = FDEP Rx BY Ry | <bit6>:<len6>
+ case 0x4c: // Rn = FDEP Rx BY Ry | <bit6>:<len6> (SE)
+ case 0x48: // Rn = FEXT Rx BY Ry | <bit6>:<len6> (SE)
+ case 0x24: // Rn = Rn OR ASHIFT Rx BY Ry | <data8>
+ case 0x64: // Rn = Rn OR FDEP Rx BY Ry | <bit6>:<len6>
+ case 0x6c: // Rn = Rn OR FDEP Rx BY Ry | <bit6>:<len6> (SE)
+ case 0x80: // Rn = EXP Rx
+ case 0x84: // Rn = EXP Rx (EX)
+ case 0x88: // Rn = LEFTZ Rx
+ case 0x8c: // Rn = LEFTO Rx
+ case 0x90: // Rn = FPACK Fx
+ case 0x94: // Fn = FUNPACK Rx
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+
+ case 0x08: // Rn = ROT Rx BY Ry | <data8>
+ {
+ code_label shift_neg = compiler->labelnum++;
+ code_label shift_end = compiler->labelnum++;
+
+ UML_MOV(block, I0, REG(ry));
+ UML_CMP(block, I0, 0);
+ UML_JMPc(block, COND_L, shift_neg);
+ UML_ROL(block, I1, REG(rx), I0);
+ UML_JMP(block, shift_end);
+ UML_LABEL(block, shift_neg);
+ UML_SUB(block, I2, 0, I0);
+ UML_ROR(block, I1, REG(rx), I2);
+ UML_LABEL(block, shift_end);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED) UML_MOV(block, ASTAT_SV, 0);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ UML_MOV(block, REG(rn), I1);
+ return;
+ }
+
+ case 0x20: // Rn = Rn OR LSHIFT Rx BY Ry | <data8>
+ {
+ code_label shift_neg = compiler->labelnum++;
+ code_label shift_end = compiler->labelnum++;
+
+ UML_MOV(block, I0, REG(ry));
+ UML_CMP(block, I0, 0);
+ UML_JMPc(block, COND_L, shift_neg);
+ UML_SHL(block, I1, REG(rx), I0);
+ UML_JMP(block, shift_end);
+ UML_LABEL(block, shift_neg);
+ UML_SUB(block, I2, 0, I0);
+ UML_SHR(block, I1, REG(rx), I2);
+ UML_LABEL(block, shift_end);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED)
+ {
+ UML_CMP(block, I0, 0);
+ UML_SETc(block, COND_NZ, ASTAT_SV);
+ }
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ UML_OR(block, REG(rn), REG(rn), I1);
+
+ return;
+ }
+
+ case 0x40: // Rn = FEXT Rx BY Ry | <bit6>:<len6>
+ // extraction mask
+ UML_MOV(block, I0, REG(ry));
+ UML_SHR(block, I1, I0, 6);
+ UML_AND(block, I1, I1, 0x3f); // i1 = len6
+ UML_AND(block, I0, I0, 0x3f); // i0 = bit6
+ UML_MOV(block, I3, 0xffffffff);
+ UML_SUB(block, I2, 32, I1);
+ UML_SHR(block, I3, I3, I2);
+ UML_SHL(block, I3, I3, I0);
+
+ UML_AND(block, I2, REG(rx), I3);
+ UML_SHR(block, REG(rn), I2, I0);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED)
+ {
+ UML_ADD(block, I0, I0, I1);
+ UML_CMP(block, I0, 32);
+ UML_SETc(block, COND_G, ASTAT_SV);
+ }
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ return;
+
+ case 0xc0: // Rn = BSET Rx BY Ry | <data8>
+ {
+ UML_MOV(block, I0, REG(ry));
+ UML_MOV(block, I1, 1);
+ UML_SHL(block, I1, I1, I0);
+ UML_OR(block, REG(rn), REG(rn), I1);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED)
+ {
+ UML_CMP(block, I0, 31);
+ UML_SETc(block, COND_G, ASTAT_SV);
+ }
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ return;
+ }
+
+ case 0xcc: // BTST Rx BY Ry | <data8>
+ {
+ UML_MOV(block, I0, REG(ry));
+ UML_MOV(block, I1, 1);
+ UML_SHL(block, I1, I1, I0);
+ UML_TEST(block, REG(rx), I1);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED)
+ UML_CMP(block, I0, 31);
+ if (SV_CALC_REQUIRED) UML_SETc(block, COND_G, ASTAT_SV);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ return;
+ }
+
+ default:
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+ }
+ break;
+ }
+
+ default:
+ generate_unimplemented_compute(block, compiler, desc);
+ return;
+ }
+ }
+}
+
+void adsp21062_device::generate_if_condition(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int condition, int skip_label)
+{
+ // Jump to skip_label if condition is not true
+ code_label not_skip;
+
+ switch (condition)
+ {
+ case 0x00: /* EQ */
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x01: /* LT */
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_NE, skip_label);
+ UML_TEST(block, ASTAT_AN, 1);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x02: /* LE */
+ not_skip = compiler->labelnum++;
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_NZ, not_skip);
+ UML_TEST(block, ASTAT_AN, 1);
+ UML_JMPc(block, COND_NZ, not_skip);
+ UML_JMP(block, skip_label);
+ UML_LABEL(block, not_skip);
+ break;
+ case 0x03: /* AC */
+ UML_TEST(block, ASTAT_AC, 1);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x04: /* AV */
+ UML_TEST(block, ASTAT_AV, 1);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x05: /* MV */
+ UML_TEST(block, ASTAT_MV, 1);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x06: /* MS */
+ UML_TEST(block, ASTAT_MN, 1);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x07: /* SV */
+ UML_TEST(block, ASTAT_SV, 1);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x08: /* SZ */
+ UML_TEST(block, ASTAT_SZ, 1);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x09: /* FLAG0 */
+ UML_CMP(block, FLAG0, 0);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x0a: /* FLAG1 */
+ UML_CMP(block, FLAG1, 0);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x0b: /* FLAG2 */
+ UML_CMP(block, FLAG2, 0);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x0c: /* FLAG3 */
+ UML_CMP(block, FLAG3, 0);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x0d: /* TF */
+ UML_TEST(block, ASTAT_BTF, 1);
+ UML_JMPc(block, COND_E, skip_label);
+ case 0x0e: /* BM */
+ UML_JMP(block, skip_label);
+ case 0x0f: /* NOT LCE */
+ UML_CMP(block, CURLCNTR, 1);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x10: /* NOT EQUAL */
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x11: /* GE */
+ not_skip = compiler->labelnum++;
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_NZ, not_skip);
+ UML_TEST(block, ASTAT_AN, 1);
+ UML_JMPc(block, COND_Z, not_skip);
+ UML_JMP(block, skip_label);
+ UML_LABEL(block, not_skip);
+ break;
+ case 0x12: /* GT */
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ UML_TEST(block, ASTAT_AN, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ break;
+ case 0x13: /* NOT AC */
+ UML_TEST(block, ASTAT_AC, 1);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x14: /* NOT AV */
+ UML_TEST(block, ASTAT_AV, 1);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x15: /* NOT MV */
+ UML_TEST(block, ASTAT_MV, 1);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x16: /* NOT MS */
+ UML_TEST(block, ASTAT_MN, 1);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x17: /* NOT SV */
+ UML_TEST(block, ASTAT_SV, 1);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x18: /* NOT SZ */
+ UML_TEST(block, ASTAT_SZ, 1);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x19: /* NOT FLAG0 */
+ UML_CMP(block, FLAG0, 0);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x1a: /* NOT FLAG1 */
+ UML_CMP(block, FLAG1, 0);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x1b: /* NOT FLAG2 */
+ UML_CMP(block, FLAG2, 0);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x1c: /* NOT FLAG3 */
+ UML_CMP(block, FLAG3, 0);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x1d: /* NOT TF */
+ UML_TEST(block, ASTAT_BTF, 1);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x1e: /* NOT BM */
+ fatalerror("generate_if_condition 0x1e"); // should not happen
+ break;
+ case 0x1f: /* TRUE */
+ fatalerror("generate_if_condition 0x1f"); // should not happen
+ break;
+ }
+}
+
+void adsp21062_device::generate_do_condition(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int condition, int skip_label, ASTAT_DRC &astat)
+{
+ // Jump to skip_label if condition is true
+ code_label not_skip;
+
+ UML_JMP(block, skip_label);
+ return;
+
+ switch (condition)
+ {
+ case 0x00: /* EQ */
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ break;
+ case 0x01: /* LT */
+ not_skip = compiler->labelnum++;
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_NZ, not_skip);
+ UML_TEST(block, ASTAT_AN, 1);
+ UML_JMPc(block, COND_Z, not_skip);
+ UML_JMP(block, skip_label);
+ UML_LABEL(block, not_skip);
+ break;
+ case 0x02: /* LE */
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ UML_TEST(block, ASTAT_AN, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ break;
+ case 0x03: /* AC */
+ UML_TEST(block, ASTAT_AC, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ break;
+ case 0x04: /* AV */
+ UML_TEST(block, ASTAT_AV, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ break;
+ case 0x05: /* MV */
+ UML_TEST(block, ASTAT_MV, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ break;
+ case 0x06: /* MS */
+ UML_TEST(block, ASTAT_MN, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ break;
+ case 0x07: /* SV */
+ UML_TEST(block, ASTAT_SV, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ break;
+ case 0x08: /* SZ */
+ UML_TEST(block, ASTAT_SZ, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ break;
+ case 0x09: /* FLAG0 */
+ UML_CMP(block, FLAG0, 0);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x0a: /* FLAG1 */
+ UML_CMP(block, FLAG1, 0);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x0b: /* FLAG2 */
+ UML_CMP(block, FLAG2, 0);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x0c: /* FLAG3 */
+ UML_CMP(block, FLAG3, 0);
+ UML_JMPc(block, COND_NE, skip_label);
+ break;
+ case 0x0d: /* TF */
+ UML_TEST(block, ASTAT_BTF, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ break;
+ case 0x0e: /* BM */
+ // infinite loop
+ break;
+ case 0x0f: /* LCE */
+ fatalerror("generate_do_condition 0x0f"); // this should only be used with counter loops
+ break;
+ case 0x10: /* NOT EQUAL */
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_Z, skip_label);
+ break;
+ case 0x11: /* GE */
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_NZ, skip_label);
+ UML_TEST(block, ASTAT_AN, 1);
+ UML_JMPc(block, COND_Z, skip_label);
+ break;
+ case 0x12: /* GT */
+ not_skip = compiler->labelnum++;
+ UML_TEST(block, ASTAT_AZ, 1);
+ UML_JMPc(block, COND_NZ, not_skip);
+ UML_TEST(block, ASTAT_AN, 1);
+ UML_JMPc(block, COND_NZ, not_skip);
+ UML_JMP(block, skip_label);
+ UML_LABEL(block, not_skip);
+ break;
+ case 0x13: /* NOT AC */
+ UML_TEST(block, ASTAT_AC, 1);
+ UML_JMPc(block, COND_Z, skip_label);
+ break;
+ case 0x14: /* NOT AV */
+ UML_TEST(block, ASTAT_AV, 1);
+ UML_JMPc(block, COND_Z, skip_label);
+ break;
+ case 0x15: /* NOT MV */
+ UML_TEST(block, ASTAT_MV, 1);
+ UML_JMPc(block, COND_Z, skip_label);
+ break;
+ case 0x16: /* NOT MS */
+ UML_TEST(block, ASTAT_MN, 1);
+ UML_JMPc(block, COND_Z, skip_label);
+ break;
+ case 0x17: /* NOT SV */
+ UML_TEST(block, ASTAT_SV, 1);
+ UML_JMPc(block, COND_Z, skip_label);
+ break;
+ case 0x18: /* NOT SZ */
+ UML_TEST(block, ASTAT_SZ, 1);
+ UML_JMPc(block, COND_Z, skip_label);
+ break;
+ case 0x19: /* NOT FLAG0 */
+ UML_CMP(block, FLAG0, 0);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x1a: /* NOT FLAG1 */
+ UML_CMP(block, FLAG1, 0);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x1b: /* NOT FLAG2 */
+ UML_CMP(block, FLAG2, 0);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x1c: /* NOT FLAG3 */
+ UML_CMP(block, FLAG3, 0);
+ UML_JMPc(block, COND_E, skip_label);
+ break;
+ case 0x1d: /* NOT TF */
+ UML_TEST(block, ASTAT_BTF, 1);
+ UML_JMPc(block, COND_Z, skip_label);
+ break;
+ case 0x1e: /* NOT BM */
+ // always true
+ UML_JMP(block, skip_label);
+ break;
+ case 0x1f: /* FALSE (FOREVER) */
+ // infinite loop
+ break;
+ }
+}
+
+void adsp21062_device::generate_shift_imm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int data, int shiftop, int rn, int rx)
+{
+ INT8 shift = data & 0xff;
+ int bit = data & 0x3f;
+ int len = (data >> 6) & 0x3f;
+
+ switch (shiftop)
+ {
+ case 0x01: // ASHIFT Rx BY <data8>
+ case 0x11: // FDEP Rx BY <bit6>:<len6>
+ case 0x13: // FDEP Rx BY <bit6>:<len6> (SE)
+ case 0x1b: // Rn = Rn OR FDEP Rx BY <bit6>:<len6> (SE)
+ UML_MOV(block, mem(&m_core->pc), desc->pc);
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr.q[0]);
+ UML_CALLC(block, cfunc_unimplemented_shiftimm, this);
+ break;
+
+ case 0x00: // LSHIFT Rx BY <data8>
+ if (abs(shift) >= 32)
+ {
+ UML_MOV(block, REG(rn), 0);
+ if (SZ_CALC_REQUIRED) UML_MOV(block, ASTAT_SZ, 1);
+ if (SV_CALC_REQUIRED) UML_MOV(block, ASTAT_SV, 1);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ }
+ else
+ {
+ if (shift < 0)
+ UML_SHR(block, REG(rn), REG(rx), -shift);
+ else
+ UML_SHL(block, REG(rn), REG(rx), shift);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED && shift != 0) UML_MOV(block, ASTAT_SV, 1);
+ if (SV_CALC_REQUIRED && shift == 0) UML_MOV(block, ASTAT_SV, 0);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ }
+ return;
+
+ case 0x02: // ROT Rx BY <data8>
+ UML_ROL(block, REG(rn), REG(rx), (shift < 0) ? 31 - ((-shift) & 0x1f) : shift & 0x1f);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED) UML_MOV(block, ASTAT_SV, 0);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ return;
+
+ case 0x08: // Rn = Rn OR LSHIFT Rx BY <data8>
+ if (abs(shift) >= 32)
+ {
+ UML_MOV(block, I0, 0);
+ if (SZ_CALC_REQUIRED) UML_MOV(block, ASTAT_SZ, 1);
+ if (SV_CALC_REQUIRED) UML_MOV(block, ASTAT_SV, 1);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ UML_OR(block, REG(rn), REG(rn), I0);
+ }
+ else
+ {
+ if (shift < 0)
+ UML_SHR(block, I0, REG(rx), -shift);
+ else
+ UML_SHL(block, I0, REG(rx), shift);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED && shift != 0) UML_MOV(block, ASTAT_SV, 1);
+ if (SV_CALC_REQUIRED && shift == 0) UML_MOV(block, ASTAT_SV, 0);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ UML_OR(block, REG(rn), REG(rn), I0);
+ }
+ return;
+
+ case 0x10: // FEXT Rx BY <bit6>:<len6>
+ if (bit == 0)
+ {
+ UML_AND(block, REG(rn), REG(rx), MAKE_EXTRACT_MASK(bit, len));
+ }
+ else
+ {
+ UML_AND(block, I0, REG(rx), MAKE_EXTRACT_MASK(bit, len));
+ UML_SHR(block, REG(rn), I0, bit);
+ }
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED && (bit + len) > 32) UML_MOV(block, ASTAT_SV, 1);
+ if (SV_CALC_REQUIRED && (bit + len) <= 32) UML_MOV(block, ASTAT_SV, 0);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ return;
+
+ case 0x12: // FEXT Rx BY <bit6>:<len6> (SE)
+ UML_AND(block, I0, REG(rx), MAKE_EXTRACT_MASK(bit, len));
+ UML_SHL(block, I0, I0, 32 - (bit + len));
+ UML_SAR(block, REG(rn), I0, 32 - (bit + len) + bit);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED && (bit + len) > 32) UML_MOV(block, ASTAT_SV, 1);
+ if (SV_CALC_REQUIRED && (bit + len) <= 32) UML_MOV(block, ASTAT_SV, 0);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ return;
+
+ case 0x19: // Rn = Rn OR FDEP Rx BY <bit6>:<len6>
+ UML_AND(block, I0, REG(rx), MAKE_EXTRACT_MASK(0, len));
+ if (bit > 0)
+ UML_SHL(block, I0, I0, bit);
+ UML_OR(block, REG(rn), REG(rn), I0);
+
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED && (bit + len) > 32) UML_MOV(block, ASTAT_SV, 1);
+ if (SV_CALC_REQUIRED && (bit + len) <= 32) UML_MOV(block, ASTAT_SV, 0);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ return;
+
+ case 0x30: // BSET Rx BY <data8>
+ UML_OR(block, REG(rn), REG(rx), 1 << data);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED && data > 31) UML_MOV(block, ASTAT_SV, 1);
+ if (SV_CALC_REQUIRED && data <= 31) UML_MOV(block, ASTAT_SV, 0);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ return;
+
+ case 0x31: // BCLR Rx By <data8>
+ UML_AND(block, REG(rn), REG(rx), ~(1 << data));
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED && data > 31) UML_MOV(block, ASTAT_SV, 1);
+ if (SV_CALC_REQUIRED && data <= 31) UML_MOV(block, ASTAT_SV, 0);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ return;
+
+ case 0x32: // BTGL Rx BY <data8>
+ UML_XOR(block, REG(rn), REG(rx), 1 << data);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED && data > 31) UML_MOV(block, ASTAT_SV, 1);
+ if (SV_CALC_REQUIRED && data <= 31) UML_MOV(block, ASTAT_SV, 0);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ return;
+
+ case 0x33: // BTST Rx BY <data8>
+ UML_TEST(block, REG(rx), 1 << data);
+ if (SZ_CALC_REQUIRED) UML_SETc(block, COND_Z, ASTAT_SZ);
+ if (SV_CALC_REQUIRED && data > 31) UML_MOV(block, ASTAT_SV, 1);
+ if (SV_CALC_REQUIRED && data <= 31) UML_MOV(block, ASTAT_SV, 0);
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, 0);
+ return;
+
+ default:
+ UML_MOV(block, mem(&m_core->pc), desc->pc);
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr.q[0]);
+ UML_CALLC(block, cfunc_unimplemented_compute, this);
+ return;
+ }
+} \ No newline at end of file
diff --git a/src/devices/cpu/sharc/sharcdsm.cpp b/src/devices/cpu/sharc/sharcdsm.cpp
index af754afe66b..b65bbeb71ea 100644
--- a/src/devices/cpu/sharc/sharcdsm.cpp
+++ b/src/devices/cpu/sharc/sharcdsm.cpp
@@ -88,14 +88,14 @@ static void compute(UINT32 opcode)
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
{
- print("R%d = R%d * R%d (SSFR), R%d = R%d + R%d, R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12, rs, rxa+8, rya+12);
+ print("R%d = R%d * R%d (SSFR), R%d = R%d + R%d, R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12);
break;
}
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
{
- print("F%d = F%d * F%d, F%d = F%d + F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12, rs, rxa+8, rya+12);
+ print("F%d = F%d * F%d, F%d = F%d + F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12);
break;
}
diff --git a/src/devices/cpu/sharc/sharcfe.cpp b/src/devices/cpu/sharc/sharcfe.cpp
new file mode 100644
index 00000000000..37e361a70c8
--- /dev/null
+++ b/src/devices/cpu/sharc/sharcfe.cpp
@@ -0,0 +1,1830 @@
+// license:BSD-3-Clause
+// copyright-holders:Ville Linde
+
+/******************************************************************************
+
+ Front-end for SHARC recompiler
+
+******************************************************************************/
+
+#include "emu.h"
+#include "sharcfe.h"
+
+#define REG_USED(desc,x) do { (desc).regin[0] |= 1 << (x); } while(0)
+#define REG_MODIFIED(desc,x) do { (desc).regout[0] |= 1 << (x); } while(0)
+
+//#define ASTAT_USED(desc) do { (desc).regin[0] |= 1 << 16; } while(0)
+//#define ASTAT_MODIFIED(desc) do { (desc).regout[0] |= 1 << 16; } while(0)
+
+#define AZ_USED(desc) do { (desc).regin[0] |= 1 << 16; } while(0)
+#define AZ_MODIFIED(desc) do { (desc).regout[0] |= 1 << 16; } while(0)
+#define AV_USED(desc) do { (desc).regin[0] |= 1 << 17; } while(0)
+#define AV_MODIFIED(desc) do { (desc).regout[0] |= 1 << 17; } while(0)
+#define AN_USED(desc) do { (desc).regin[0] |= 1 << 18; } while(0)
+#define AN_MODIFIED(desc) do { (desc).regout[0] |= 1 << 18; } while(0)
+#define AC_USED(desc) do { (desc).regin[0] |= 1 << 19; } while(0)
+#define AC_MODIFIED(desc) do { (desc).regout[0] |= 1 << 19; } while(0)
+#define AS_USED(desc) do { (desc).regin[0] |= 1 << 20; } while(0)
+#define AS_MODIFIED(desc) do { (desc).regout[0] |= 1 << 20; } while(0)
+#define AI_USED(desc) do { (desc).regin[0] |= 1 << 21; } while(0)
+#define AI_MODIFIED(desc) do { (desc).regout[0] |= 1 << 21; } while(0)
+#define MN_USED(desc) do { (desc).regin[0] |= 1 << 22; } while(0)
+#define MN_MODIFIED(desc) do { (desc).regout[0] |= 1 << 22; } while(0)
+#define MV_USED(desc) do { (desc).regin[0] |= 1 << 23; } while(0)
+#define MV_MODIFIED(desc) do { (desc).regout[0] |= 1 << 23; } while(0)
+#define MU_USED(desc) do { (desc).regin[0] |= 1 << 24; } while(0)
+#define MU_MODIFIED(desc) do { (desc).regout[0] |= 1 << 24; } while(0)
+#define MI_USED(desc) do { (desc).regin[0] |= 1 << 25; } while(0)
+#define MI_MODIFIED(desc) do { (desc).regout[0] |= 1 << 25; } while(0)
+#define SV_USED(desc) do { (desc).regin[0] |= 1 << 26; } while(0)
+#define SV_MODIFIED(desc) do { (desc).regout[0] |= 1 << 26; } while(0)
+#define SZ_USED(desc) do { (desc).regin[0] |= 1 << 27; } while(0)
+#define SZ_MODIFIED(desc) do { (desc).regout[0] |= 1 << 27; } while(0)
+#define SS_USED(desc) do { (desc).regin[0] |= 1 << 28; } while(0)
+#define SS_MODIFIED(desc) do { (desc).regout[0] |= 1 << 28; } while(0)
+#define BTF_USED(desc) do { (desc).regin[0] |= 1 << 29; } while(0)
+#define BTF_MODIFIED(desc) do { (desc).regout[0] |= 1 << 29; } while(0)
+#define AF_USED(desc) do { (desc).regin[0] |= 1 << 30; } while(0)
+#define AF_MODIFIED(desc) do { (desc).regout[0] |= 1 << 30; } while(0)
+
+#define ALU_FLAGS_MODIFIED(desc) do { AZ_MODIFIED(desc);AN_MODIFIED(desc);AV_MODIFIED(desc);AC_MODIFIED(desc);AS_MODIFIED(desc);AI_MODIFIED(desc); } while(0)
+#define MULT_FLAGS_MODIFIED(desc) do { MN_MODIFIED(desc);MV_MODIFIED(desc);MU_MODIFIED(desc);MI_MODIFIED(desc); } while(0)
+#define SHIFT_FLAGS_MODIFIED(desc) do { SZ_MODIFIED(desc);SV_MODIFIED(desc);SS_MODIFIED(desc); } while(0)
+
+
+#define PM_I_USED(desc,x) do { (desc).regin[1] |= 1 << (x); } while(0)
+#define PM_I_MODIFIED(desc,x) do { (desc).regout[1] |= 1 << (x); } while(0)
+#define PM_M_USED(desc,x) do { (desc).regin[1] |= 1 << ((x) + 8); } while(0)
+#define PM_M_MODIFIED(desc,x) do { (desc).regout[1] |= 1 << ((x) + 8); } while(0)
+#define PM_B_USED(desc,x) do { (desc).regin[1] |= 1 << ((x) + 16); } while(0)
+#define PM_B_MODIFIED(desc,x) do { (desc).regout[1] |= 1 << ((x) + 16); } while(0)
+#define PM_L_USED(desc,x) do { (desc).regin[1] |= 1 << ((x) + 24); } while(0)
+#define PM_L_MODIFIED(desc,x) do { (desc).regout[1] |= 1 << ((x) + 24); } while(0)
+
+#define DM_I_USED(desc,x) do { (desc).regin[2] |= 1 << (x); } while(0)
+#define DM_I_MODIFIED(desc,x) do { (desc).regout[2] |= 1 << (x); } while(0)
+#define DM_M_USED(desc,x) do { (desc).regin[2] |= 1 << ((x) + 8); } while(0)
+#define DM_M_MODIFIED(desc,x) do { (desc).regout[2] |= 1 << ((x) + 8); } while(0)
+#define DM_B_USED(desc,x) do { (desc).regin[2] |= 1 << ((x) + 16); } while(0)
+#define DM_B_MODIFIED(desc,x) do { (desc).regout[2] |= 1 << ((x) + 16); } while(0)
+#define DM_L_USED(desc,x) do { (desc).regin[2] |= 1 << ((x) + 24); } while(0)
+#define DM_L_MODIFIED(desc,x) do { (desc).regout[2] |= 1 << ((x) + 24); } while(0)
+
+
+sharc_frontend::sharc_frontend(adsp21062_device *sharc, UINT32 window_start, UINT32 window_end, UINT32 max_sequence)
+ : drc_frontend(*sharc, window_start, window_end, max_sequence),
+ m_sharc(sharc)
+{
+ m_loopmap = std::make_unique<LOOP_ENTRY[]>(0x20000);
+}
+
+
+
+void sharc_frontend::flush()
+{
+ LOOP_ENTRY* map = m_loopmap.get();
+
+ memset(map, 0, sizeof(LOOP_ENTRY) * 0x20000);
+}
+
+void sharc_frontend::add_loop_entry(UINT32 pc, UINT8 type, UINT32 start_pc, UINT8 looptype, UINT8 condition)
+{
+ UINT32 l2 = pc >> 17;
+ UINT32 l1 = pc & 0x1ffff;
+
+ if (l2 != 0x1)
+ fatalerror("sharc_frontend::add_loop_entry: PC = %08X", pc);
+
+ LOOP_ENTRY* map = m_loopmap.get();
+ UINT32 current_type = map[l1].entrytype;
+ if (current_type & type)
+ {
+ // check for mismatch if the entry is already used
+ if (map[l1].start_pc != start_pc ||
+ map[l1].looptype != looptype ||
+ map[l1].condition != condition)
+ {
+ fatalerror("sharc_frontend::add_loop_entry: existing entry does match: start_pc %08X/%08X, looptype %02X/%02X, cond %02X/%02X", start_pc, map[l1].start_pc, looptype, map[l1].looptype, condition, map[l1].condition);
+ }
+ }
+
+ current_type |= type;
+
+ map[l1].entrytype = current_type;
+ map[l1].looptype = looptype;
+ map[l1].condition = condition;
+ map[l1].start_pc = start_pc;
+}
+
+void sharc_frontend::insert_loop(const LOOP_DESCRIPTOR &loopdesc)
+{
+ add_loop_entry(loopdesc.start_pc, LOOP_ENTRY_START, loopdesc.start_pc, loopdesc.type, loopdesc.condition);
+ add_loop_entry(loopdesc.end_pc, LOOP_ENTRY_EVALUATION, loopdesc.start_pc, loopdesc.type, loopdesc.condition);
+ if (loopdesc.astat_check_pc != 0xffffffff)
+ add_loop_entry(loopdesc.astat_check_pc, LOOP_ENTRY_ASTAT_CHECK, loopdesc.start_pc, loopdesc.type, loopdesc.condition);
+}
+
+bool sharc_frontend::is_loop_evaluation(UINT32 pc)
+{
+ UINT32 l2 = pc >> 17;
+ UINT32 l1 = pc & 0x1ffff;
+
+ if (l2 != 0x1)
+ return false;
+
+ LOOP_ENTRY* map = m_loopmap.get();
+ if (map[l1].entrytype & LOOP_ENTRY_EVALUATION)
+ return true;
+
+ return false;
+}
+
+bool sharc_frontend::is_loop_start(UINT32 pc)
+{
+ UINT32 l2 = pc >> 17;
+ UINT32 l1 = pc & 0x1ffff;
+
+ if (l2 != 0x1)
+ return false;
+
+ LOOP_ENTRY* map = m_loopmap.get();
+ if (map[l1].entrytype & LOOP_ENTRY_START)
+ return true;
+
+ return false;
+}
+
+bool sharc_frontend::is_astat_delay_check(UINT32 pc)
+{
+ UINT32 l2 = pc >> 17;
+ UINT32 l1 = pc & 0x1ffff;
+
+ if (l2 != 0x1)
+ return false;
+
+ LOOP_ENTRY* map = m_loopmap.get();
+ if (map[l1].entrytype & LOOP_ENTRY_ASTAT_CHECK)
+ return true;
+
+ return false;
+}
+
+
+bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
+{
+ //UINT64 opcode = desc.opptr.q[0] = m_sharc.m_direct->read_qword(desc.physpc, 0);
+ UINT64 opcode = desc.opptr.q[0] = m_sharc->pm_read48(desc.physpc);
+
+ desc.length = 1;
+ desc.cycles = 1;
+
+ // handle looping
+ /*
+ if (m_loop.size() > 0)
+ {
+ for (int i = 0; i < m_loop.size(); i++)
+ {
+ LOOP_DESCRIPTOR &loop = m_loop.at(i);
+ if (loop.start_pc == desc.pc)
+ {
+ desc.flags |= OPFLAG_IS_BRANCH_TARGET;
+ }
+ if (loop.astat_check_pc == desc.pc)
+ {
+ if (loop.type == LOOP_TYPE_CONDITIONAL)
+ {
+ UINT32 flags = m_sharc->do_condition_astat_bits(loop.condition);
+ if (flags & adsp21062_device::ASTAT_FLAGS::AZ) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AZ;
+ if (flags & adsp21062_device::ASTAT_FLAGS::AN) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AN;
+ if (flags & adsp21062_device::ASTAT_FLAGS::AV) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AV;
+ if (flags & adsp21062_device::ASTAT_FLAGS::AC) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AC;
+ if (flags & adsp21062_device::ASTAT_FLAGS::MN) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_MN;
+ if (flags & adsp21062_device::ASTAT_FLAGS::MV) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_MV;
+ if (flags & adsp21062_device::ASTAT_FLAGS::SV) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_SV;
+ if (flags & adsp21062_device::ASTAT_FLAGS::SZ) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_SZ;
+ if (flags & adsp21062_device::ASTAT_FLAGS::BTF) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_BTF;
+ }
+ }
+ if (loop.end_pc == desc.pc)
+ {
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.targetpc = loop.start_pc;
+ if (loop.type == LOOP_TYPE_COUNTER)
+ {
+ desc.userflags |= OP_USERFLAG_COUNTER_LOOP;
+ }
+ else if (loop.type == LOOP_TYPE_CONDITIONAL)
+ {
+ desc.userflags |= OP_USERFLAG_COND_LOOP;
+ desc.userflags |= (loop.condition << 2) & OP_USERFLAG_COND_FIELD;
+ }
+ m_loop.erase(m_loop.begin()+i);
+ break;
+ }
+ }
+ }*/
+
+ if (is_astat_delay_check(desc.pc))
+ {
+ LOOP_ENTRY* map = m_loopmap.get();
+ int index = desc.pc & 0x1ffff;
+
+ if (map[index].looptype == LOOP_TYPE_CONDITIONAL)
+ {
+ UINT32 flags = m_sharc->do_condition_astat_bits(map[index].condition);
+ if (flags & adsp21062_device::ASTAT_FLAGS::AZ) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AZ;
+ if (flags & adsp21062_device::ASTAT_FLAGS::AN) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AN;
+ if (flags & adsp21062_device::ASTAT_FLAGS::AV) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AV;
+ if (flags & adsp21062_device::ASTAT_FLAGS::AC) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AC;
+ if (flags & adsp21062_device::ASTAT_FLAGS::MN) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_MN;
+ if (flags & adsp21062_device::ASTAT_FLAGS::MV) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_MV;
+ if (flags & adsp21062_device::ASTAT_FLAGS::SV) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_SV;
+ if (flags & adsp21062_device::ASTAT_FLAGS::SZ) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_SZ;
+ if (flags & adsp21062_device::ASTAT_FLAGS::BTF) desc.userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_BTF;
+ }
+ }
+
+ if (is_loop_start(desc.pc))
+ {
+ desc.flags |= OPFLAG_IS_BRANCH_TARGET;
+ }
+
+ if (is_loop_evaluation(desc.pc))
+ {
+ LOOP_ENTRY* map = m_loopmap.get();
+ int index = desc.pc & 0x1ffff;
+
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.targetpc = map[index].start_pc;
+ if (map[index].looptype == LOOP_TYPE_COUNTER)
+ {
+ desc.userflags |= OP_USERFLAG_COUNTER_LOOP;
+ }
+ else if (map[index].looptype == LOOP_TYPE_CONDITIONAL)
+ {
+ desc.userflags |= OP_USERFLAG_COND_LOOP;
+ desc.userflags |= (map[index].condition << 2) & OP_USERFLAG_COND_FIELD;
+ }
+ }
+
+
+ switch ((opcode >> 45) & 7)
+ {
+ case 0: // subops
+ {
+ UINT32 subop = (opcode >> 40) & 0x1f;
+ switch (subop)
+ {
+ case 0x00: // NOP / idle |000|00000|
+ if (opcode & U64(0x008000000000))
+ {
+ // IDLE
+ desc.flags |= OPFLAG_END_SEQUENCE;
+ }
+ else
+ {
+ // NOP
+ }
+ break;
+
+ case 0x01: // compute |000|00001|
+ {
+ int cond = (opcode >> 33) & 0x1f;
+ describe_if_condition(desc, cond);
+
+ if (!describe_compute(desc, opcode))
+ return false;
+ break;
+ }
+
+ case 0x02: // immediate shift |000|00010|
+ {
+ int shiftop = (opcode >> 16) & 0x3f;
+ int rn = (opcode >> 4) & 0xf;
+ int rx = (opcode & 0xf);
+ int cond = (opcode >> 33) & 0x1f;
+
+ describe_if_condition(desc, cond);
+
+ if (!describe_shiftop_imm(desc, shiftop, rn, rx))
+ return false;
+ break;
+ }
+
+ case 0x04: // compute / modify |000|00100|
+ {
+ int g = (opcode >> 38) & 0x1;
+ int m = (opcode >> 27) & 0x7;
+ int i = (opcode >> 30) & 0x7;
+ int cond = (opcode >> 33) & 0x1f;
+
+ describe_if_condition(desc, cond);
+
+ if (!describe_compute(desc, opcode))
+ return false;
+
+ if (g)
+ {
+ // PM
+ PM_I_USED(desc, i);
+ PM_I_MODIFIED(desc, i);
+ PM_M_USED(desc, m);
+ }
+ else
+ {
+ // DM
+ DM_I_USED(desc, i);
+ DM_I_MODIFIED(desc, i);
+ DM_M_USED(desc, m);
+ }
+ break;
+ }
+
+ case 0x06: // direct jump|call |000|00110|
+ {
+ int j = (opcode >> 26) & 0x1;
+ int cond = (opcode >> 33) & 0x1f;
+ UINT32 address = opcode & 0xffffff;
+
+ if (m_sharc->if_condition_always_true(cond))
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ else
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+
+ describe_if_condition(desc, cond);
+
+ desc.targetpc = address;
+ desc.delayslots = (j) ? 2 : 0;
+ break;
+ }
+
+ case 0x07: // direct jump|call |000|00111|
+ {
+ int j = (opcode >> 26) & 0x1;
+ int cond = (opcode >> 33) & 0x1f;
+ UINT32 address = opcode & 0xffffff;
+
+ if (m_sharc->if_condition_always_true(cond))
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ else
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+
+ describe_if_condition(desc, cond);
+
+ desc.targetpc = desc.pc + SIGN_EXTEND24(address);
+ desc.delayslots = (j) ? 2 : 0;
+ break;
+ }
+
+ case 0x08: // indirect jump|call / compute |000|01000|
+ {
+ int j = (opcode >> 26) & 0x1;
+ int pmi = (opcode >> 30) & 0x7;
+ int pmm = (opcode >> 27) & 0x7;
+ int cond = (opcode >> 33) & 0x1f;
+
+ if (!describe_compute(desc, opcode))
+ return false;
+
+ if (m_sharc->if_condition_always_true(cond))
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ else
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+
+ describe_if_condition(desc, cond);
+
+ PM_I_USED(desc, pmi);
+ PM_M_USED(desc, pmm);
+
+ desc.targetpc = BRANCH_TARGET_DYNAMIC;
+ desc.delayslots = (j) ? 2 : 0;
+ break;
+ }
+
+ case 0x09: // indirect jump|call / compute |000|01001|
+ {
+ int j = (opcode >> 26) & 0x1;;
+ int cond = (opcode >> 33) & 0x1f;
+
+ if (!describe_compute(desc, opcode))
+ return false;
+
+ if (m_sharc->if_condition_always_true(cond))
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ else
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+
+ describe_if_condition(desc, cond);
+
+ desc.targetpc = desc.pc + SIGN_EXTEND6((opcode >> 27) & 0x3f);
+ desc.delayslots = (j) ? 2 : 0;
+
+ break;
+ }
+
+ case 0x0a: // return from subroutine / compute |000|01010|
+ {
+ int cond = (opcode >> 33) & 0x1f;
+ int j = (opcode >> 26) & 0x1;
+
+ if (!describe_compute(desc, opcode))
+ return false;
+
+ if (m_sharc->if_condition_always_true(cond))
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ else
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+
+ describe_if_condition(desc, cond);
+
+ desc.targetpc = BRANCH_TARGET_DYNAMIC;
+ desc.delayslots = (j) ? 2 : 0;
+ break;
+ }
+
+ case 0x0b: // return from interrupt / compute |000|01011|
+ {
+ int cond = (opcode >> 33) & 0x1f;
+ int j = (opcode >> 26) & 0x1;
+
+ if (!describe_compute(desc, opcode))
+ return false;
+
+ if (m_sharc->if_condition_always_true(cond))
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ else
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+
+ describe_if_condition(desc, cond);
+
+ desc.targetpc = BRANCH_TARGET_DYNAMIC;
+ desc.delayslots = (j) ? 2 : 0;
+ break;
+ }
+
+ case 0x0c: // do until counter expired |000|01100|
+ {
+ int offset = SIGN_EXTEND24(opcode & 0xffffff);
+
+ LOOP_DESCRIPTOR loop;
+ loop.start_pc = desc.pc + 1;
+ loop.end_pc = desc.pc + offset;
+ loop.astat_check_pc = 0xffffffff;
+ loop.type = LOOP_TYPE_COUNTER;
+ loop.condition = 0;
+
+ insert_loop(loop);
+ break;
+ }
+
+ case 0x0d: // do until counter expired |000|01101|
+ {
+ int ureg = (opcode >> 32) & 0xff;
+ if (!describe_ureg_access(desc, ureg, UREG_READ))
+ return false;
+
+ int offset = SIGN_EXTEND24(opcode & 0xffffff);
+
+ LOOP_DESCRIPTOR loop;
+ loop.start_pc = desc.pc + 1;
+ loop.end_pc = desc.pc + offset;
+ loop.astat_check_pc = 0xffffffff;
+ loop.type = LOOP_TYPE_COUNTER;
+ loop.condition = 0;
+
+ insert_loop(loop);
+ break;
+ }
+
+ case 0x0e: // do until |000|01110|
+ {
+ int offset = SIGN_EXTEND24(opcode & 0xffffff);
+ int cond = (opcode >> 33) & 0x1f;
+
+ LOOP_DESCRIPTOR loop;
+ loop.start_pc = desc.pc + 1;
+ loop.end_pc = desc.pc + offset;
+ loop.type = LOOP_TYPE_CONDITIONAL;
+ loop.condition = cond;
+
+ loop.astat_check_pc = loop.end_pc - 2;
+ if (loop.astat_check_pc < loop.start_pc)
+ fatalerror("describe_compute: conditional loop < 2 at %08X", desc.pc);
+
+ insert_loop(loop);
+ break;
+ }
+
+ case 0x0f: // immediate data -> ureg |000|01111|
+ {
+ int ureg = (opcode >> 32) & 0xff;
+ if (!describe_ureg_access(desc, ureg, UREG_WRITE))
+ return false;
+ break;
+ }
+
+ case 0x10: // ureg <-> DM|PM (direct) |000|100|G|D|
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ {
+ int ureg = (opcode >> 32) & 0xff;
+ int d = (opcode >> 40) & 1;
+ if (d)
+ {
+ if (!describe_ureg_access(desc, ureg, UREG_READ))
+ return false;
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+ }
+ else
+ {
+ if (!describe_ureg_access(desc, ureg, UREG_WRITE))
+ return false;
+ desc.flags |= OPFLAG_READS_MEMORY;
+ }
+ break;
+ }
+
+ case 0x14: // system register bit manipulation |000|10100|
+ {
+ int bop = (opcode >> 37) & 0x7;
+ int sreg = (opcode >> 32) & 0xf;
+ UINT32 data = (UINT32)(opcode);
+
+ switch (bop)
+ {
+ case 0: // SET
+ case 1: // CLEAR
+ case 2: // TOGGLE
+ if (sreg == 0x7c) // ASTAT
+ {
+ if (data & adsp21062_device::AZ)
+ {
+ AZ_USED(desc); AZ_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::AV)
+ {
+ AV_USED(desc); AV_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::AN)
+ {
+ AN_USED(desc); AN_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::AC)
+ {
+ AC_USED(desc); AC_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::AS)
+ {
+ AS_USED(desc); AS_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::AI)
+ {
+ AI_USED(desc); AI_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::MN)
+ {
+ MN_USED(desc); MN_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::MV)
+ {
+ MV_USED(desc); MV_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::MU)
+ {
+ MU_USED(desc); MU_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::MI)
+ {
+ MI_USED(desc); MI_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::SV)
+ {
+ SV_USED(desc); SV_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::SZ)
+ {
+ SZ_USED(desc); SZ_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::SS)
+ {
+ SS_USED(desc); SS_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::BTF)
+ {
+ BTF_USED(desc); BTF_MODIFIED(desc);
+ }
+ if (data & adsp21062_device::AF)
+ {
+ AF_USED(desc); AF_MODIFIED(desc);
+ }
+ }
+ break;
+
+ case 4: // TEST
+ case 5: // XOR
+ BTF_MODIFIED(desc);
+ break;
+
+ default:
+ fatalerror("sharc_frontend::describe: system reg bit manipulation %d", bop);
+ return false;
+ }
+ break;
+ }
+
+ case 0x16: // I register modify / bit-reverse |000|10110|
+ {
+ if (opcode & U64(0x008000000000)) // bit reverse
+ {
+ fatalerror("sharc_frontend::describe: bit reverse unimplemented");
+ }
+ else // modify
+ {
+ int g = (opcode >> 38) & 0x1;
+ int i = (opcode >> 32) & 0x7;
+
+ if (g)
+ PM_I_USED(desc, i);
+ else
+ DM_I_USED(desc, i);
+ }
+ break;
+ }
+
+ case 0x17: // push|pop stacks / flush cache |000|10111|
+ break;
+
+ case 0x18: // cjump |000|11000|
+ fatalerror("sharc_frontend::describe: cjump unimplemented");
+ break;
+
+ case 0x19: // rframe |000|11001|
+ fatalerror("sharc_frontend::describe: rframe unimplemented");
+ break;
+
+ default:
+ fatalerror("sharc_frontend::describe: unknown subop %02X in opcode %04X%08X", subop, (UINT16)(opcode >> 32), (UINT32)(opcode));
+ return false;
+ }
+ break;
+ }
+
+ case 1: // compute / dreg <-> DM / dreg <-> PM |001|
+ {
+ if (!describe_compute(desc, opcode))
+ return false;
+
+ int pm_dreg = (opcode >> 23) & 0xf;
+ int pmm = (opcode >> 27) & 0x7;
+ int pmi = (opcode >> 30) & 0x7;
+ int dm_dreg = (opcode >> 33) & 0xf;
+ int dmm = (opcode >> 38) & 0x7;
+ int dmi = (opcode >> 41) & 0x7;
+ int pmd = (opcode >> 37) & 0x1;
+ int dmd = (opcode >> 44) & 0x1;
+
+ PM_I_USED(desc, pmi);
+ PM_I_MODIFIED(desc, pmi);
+ PM_M_USED(desc, pmm);
+
+ if (pmd)
+ {
+ REG_USED(desc, pm_dreg);
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+ }
+ else
+ {
+ REG_MODIFIED(desc, pm_dreg);
+ desc.flags |= OPFLAG_READS_MEMORY;
+ }
+
+ DM_I_USED(desc, dmi);
+ DM_I_MODIFIED(desc, dmi);
+ DM_M_USED(desc, dmm);
+
+ if (dmd)
+ {
+ REG_USED(desc, dm_dreg);
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+ }
+ else
+ {
+ REG_MODIFIED(desc, dm_dreg);
+ desc.flags |= OPFLAG_READS_MEMORY;
+ }
+ break;
+ }
+
+ case 2: // compute / ureg <-> DM|PM, register modify |010|
+ {
+ if (!describe_compute(desc, opcode))
+ return false;
+
+ int i = (opcode >> 41) & 0x7;
+ int m = (opcode >> 38) & 0x7;
+ int cond = (opcode >> 33) & 0x1f;
+ int g = (opcode >> 32) & 0x1;
+ int d = (opcode >> 31) & 0x1;
+ int ureg = (opcode >> 23) & 0xff;
+
+ describe_if_condition(desc, cond);
+
+ if (d)
+ {
+ if (!describe_ureg_access(desc, ureg, UREG_READ))
+ return false;
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+ }
+ else
+ {
+ if (!describe_ureg_access(desc, ureg, UREG_WRITE))
+ return false;
+ desc.flags |= OPFLAG_READS_MEMORY;
+ }
+
+ if (g)
+ {
+ // PM
+ PM_I_USED(desc, i);
+ PM_M_USED(desc, m);
+ }
+ else
+ {
+ // DM
+ DM_I_USED(desc, i);
+ DM_M_USED(desc, m);
+ }
+
+ break;
+ }
+
+ case 3:
+ {
+ if (!describe_compute(desc, opcode))
+ return false;
+
+ if (opcode & U64(0x100000000000)) // compute / ureg <-> ureg |011|1|
+ {
+ int src_ureg = (opcode >> 36) & 0xff;
+ int dst_ureg = (opcode >> 23) & 0xff;
+ int cond = (opcode >> 31) & 0x1f;
+
+ describe_if_condition(desc, cond);
+
+ if (!describe_ureg_access(desc, src_ureg, UREG_READ))
+ return false;
+ if (!describe_ureg_access(desc, dst_ureg, UREG_WRITE))
+ return false;
+ }
+ else // compute / dreg <-> DM|PM, immediate modify |011|0|
+ {
+ int u = (opcode >> 38) & 0x1;
+ int d = (opcode >> 39) & 0x1;
+ int g = (opcode >> 40) & 0x1;
+ int dreg = (opcode >> 23) & 0xf;
+ int i = (opcode >> 41) & 0x7;
+ int cond = (opcode >> 33) & 0x1f;
+
+ describe_if_condition(desc, cond);
+
+ if (d)
+ {
+ REG_USED(desc, dreg);
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+ }
+ else
+ {
+ REG_MODIFIED(desc, dreg);
+ desc.flags |= OPFLAG_READS_MEMORY;
+ }
+
+ if (g)
+ {
+ // PM
+ PM_I_USED(desc, i);
+
+ if (u) // post-modify with update
+ {
+ PM_I_MODIFIED(desc, i);
+ }
+ }
+ else
+ {
+ // DM
+ DM_I_USED(desc, i);
+
+ if (u) // post-modify with update
+ {
+ DM_I_MODIFIED(desc, i);
+ }
+ }
+ }
+ break;
+ }
+
+ case 4:
+ {
+ if (opcode & U64(0x100000000000)) // immediate data -> DM|PM |100|1|
+ {
+ int i = (opcode >> 41) & 0x7;
+ int m = (opcode >> 38) & 0x7;
+ int g = (opcode >> 37) & 0x1;
+
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+
+ if (g)
+ {
+ // PM
+ PM_I_USED(desc, i);
+ PM_I_MODIFIED(desc, i);
+ PM_M_USED(desc, m);
+ }
+ else
+ {
+ // DM
+ DM_I_USED(desc, i);
+ DM_I_MODIFIED(desc, i);
+ DM_M_USED(desc, m);
+ }
+ }
+ else // immediate shift / dreg <-> DM|PM |100|0|
+ {
+ int i = (opcode >> 41) & 0x7;
+ int m = (opcode >> 38) & 0x7;
+ int g = (opcode >> 32) & 0x1;
+ int d = (opcode >> 31) & 0x1;
+ int dreg = (opcode >> 23) & 0xf;
+ int shiftop = (opcode >> 16) & 0x3f;
+ int rn = (opcode >> 4) & 0xf;
+ int rx = (opcode & 0xf);
+ int cond = (opcode >> 33) & 0x1f;
+
+ describe_if_condition(desc, cond);
+
+ if (!describe_shiftop_imm(desc, shiftop, rn, rx))
+ return false;
+
+ if (d)
+ {
+ REG_USED(desc, dreg);
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+ }
+ else
+ {
+ REG_MODIFIED(desc, dreg);
+ desc.flags |= OPFLAG_READS_MEMORY;
+ }
+
+ if (g)
+ {
+ // PM
+ PM_I_USED(desc, i);
+ PM_I_MODIFIED(desc, i);
+ PM_M_USED(desc, m);
+ }
+ else
+ {
+ // DM
+ DM_I_USED(desc, i);
+ DM_I_MODIFIED(desc, i);
+ DM_M_USED(desc, m);
+ }
+ }
+ break;
+ }
+
+ case 5: // ureg <-> DM|PM (indirect) |101|
+ {
+ int ureg = (opcode >> 32) & 0xff;
+ int d = (opcode >> 40) & 1;
+ int i = (opcode >> 41) & 0x7;
+ int g = (opcode >> 44) & 1;
+
+ if (d)
+ {
+ if (!describe_ureg_access(desc, ureg, UREG_READ))
+ return false;
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+ }
+ else
+ {
+ if (!describe_ureg_access(desc, ureg, UREG_WRITE))
+ return false;
+ desc.flags |= OPFLAG_READS_MEMORY;
+ }
+
+ if (g)
+ PM_I_USED(desc, i);
+ else
+ DM_I_USED(desc, i);
+ break;
+ }
+
+ case 6: // indirect jump / compute / dreg <-> DM |110|
+ {
+ int d = (opcode >> 44) & 0x1;
+ int dmi = (opcode >> 41) & 0x7;
+ int dmm = (opcode >> 38) & 0x7;
+ int pmi = (opcode >> 30) & 0x7;
+ int pmm = (opcode >> 27) & 0x7;
+ int cond = (opcode >> 33) & 0x1f;
+ int dreg = (opcode >> 23) & 0xf;
+
+ if (!describe_compute(desc, opcode))
+ return false;
+
+ if (m_sharc->if_condition_always_true(cond))
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ else
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+
+ describe_if_condition(desc, cond);
+
+ PM_I_USED(desc, pmi);
+ PM_M_USED(desc, pmm);
+ DM_I_USED(desc, dmi);
+ DM_I_MODIFIED(desc, dmi);
+ DM_M_USED(desc, dmm);
+
+ if (d)
+ {
+ REG_USED(desc, dreg);
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+ }
+ else
+ {
+ REG_MODIFIED(desc, dreg);
+ desc.flags |= OPFLAG_READS_MEMORY;
+ }
+
+ desc.targetpc = BRANCH_TARGET_DYNAMIC;
+ desc.delayslots = 0;
+ break;
+ }
+
+ case 7: // indirect jump / compute / dreg <-> DM |111|
+ {
+ int d = (opcode >> 44) & 0x1;
+ int dmi = (opcode >> 41) & 0x7;
+ int dmm = (opcode >> 38) & 0x7;
+ int cond = (opcode >> 33) & 0x1f;
+ int dreg = (opcode >> 23) & 0xf;
+
+ if (!describe_compute(desc, opcode))
+ return false;
+
+ if (m_sharc->if_condition_always_true(cond))
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ else
+ desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+
+ describe_if_condition(desc, cond);
+
+ DM_I_USED(desc, dmi);
+ DM_I_MODIFIED(desc, dmi);
+ DM_M_USED(desc, dmm);
+
+ if (d)
+ {
+ REG_USED(desc, dreg);
+ desc.flags |= OPFLAG_WRITES_MEMORY;
+ }
+ else
+ {
+ REG_MODIFIED(desc, dreg);
+ desc.flags |= OPFLAG_READS_MEMORY;
+ }
+
+ desc.targetpc = desc.pc + SIGN_EXTEND6((opcode >> 27) & 0x3f);
+ desc.delayslots = 0;
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool sharc_frontend::describe_compute(opcode_desc &desc, UINT64 opcode)
+{
+ // skip if no-op
+ if ((opcode & 0x7fffff) == 0)
+ return true;
+
+ int rs = (opcode >> 12) & 0xf;
+ int rn = (opcode >> 8) & 0xf;
+ int ra = rn;
+ int rx = (opcode >> 4) & 0xf;
+ int ry = (opcode >> 0) & 0xf;
+
+ if (opcode & 0x400000) // multi-function operation
+ {
+ UINT32 multiop = (opcode >> 16) & 0x3f;
+ int fm = rs;
+ int fa = rn;
+ int fxm = (opcode >> 6) & 0x3; // registers 0 - 3
+ int fym = ((opcode >> 4) & 0x3) + 4; // registers 4 - 7
+ int fxa = ((opcode >> 2) & 0x3) + 8; // registers 8 - 11
+ int fya = (opcode & 0x3) + 12; // registers 12 - 15
+
+ switch (multiop)
+ {
+ case 0x00: // Rn = MRxx
+ REG_MODIFIED(desc, rn);
+ break;
+ case 0x01: // MRxx = Rn
+ REG_USED(desc, rn);
+ break;
+
+ case 0x07: // Ra = Rx + Ry, Rs = Rx - Ry
+ case 0x0f: // Fa = Fx + Fy, Fs = Fx - Fy
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, ra);
+ REG_MODIFIED(desc, rs);
+ ALU_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x04: // Rm = R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12
+ case 0x05: // Rm = R3-0 * R7-4 (SSFR), Ra = R11-8 - R15-12
+ case 0x06: // Rm = R3-0 * R7-4 (SSFR), Ra = (R11-8 + R15-12) / 2
+ REG_USED(desc, fxm);
+ REG_USED(desc, fym);
+ REG_USED(desc, fxa);
+ REG_USED(desc, fya);
+ REG_MODIFIED(desc, fm);
+ REG_MODIFIED(desc, fa);
+ ALU_FLAGS_MODIFIED(desc);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x08: // MRF = MRF + R3-0 * R7-4 (SSF), Ra = R11-8 + R15-12
+ case 0x09: // MRF = MRF + R3-0 * R7-4 (SSF), Ra = R11-8 - R15-12
+ case 0x0a: // MRF = MRF + R3-0 * R7-4 (SSF), Ra = (R11-8 + R15-12) / 2
+ REG_USED(desc, fxm);
+ REG_USED(desc, fym);
+ REG_USED(desc, fxa);
+ REG_USED(desc, fya);
+ ALU_FLAGS_MODIFIED(desc);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x0c: // Rm = MRF + R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12
+ case 0x0d: // Rm = MRF + R3-0 * R7-4 (SSFR), Ra = R11-8 - R15-12
+ case 0x0e: // Rm = MRF + R3-0 * R7-4 (SSFR), Ra = (R11-8 + R15-12) / 2
+ REG_USED(desc, fxm);
+ REG_USED(desc, fym);
+ REG_USED(desc, fxa);
+ REG_USED(desc, fya);
+ REG_MODIFIED(desc, fm);
+ REG_MODIFIED(desc, fa);
+ ALU_FLAGS_MODIFIED(desc);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x10: // MRF = MRF - R3-0 * R7-4 (SSF), Ra = R11-8 + R15-12
+ case 0x11: // MRF = MRF - R3-0 * R7-4 (SSF), Ra = R11-8 - R15-12
+ case 0x12: // MRF = MRF - R3-0 * R7-4 (SSF), Ra = (R11-8 + R15-12) / 2
+ REG_USED(desc, fxm);
+ REG_USED(desc, fym);
+ REG_USED(desc, fxa);
+ REG_USED(desc, fya);
+ ALU_FLAGS_MODIFIED(desc);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x14: // Rm = MRF - R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12
+ case 0x15: // Rm = MRF - R3-0 * R7-4 (SSFR), Ra = R11-8 - R15-12
+ case 0x16: // Rm = MRF - R3-0 * R7-4 (SSFR), Ra = (R11-8 + R15-12) / 2
+ REG_USED(desc, fxm);
+ REG_USED(desc, fym);
+ REG_USED(desc, fxa);
+ REG_USED(desc, fya);
+ REG_MODIFIED(desc, fm);
+ REG_MODIFIED(desc, fa);
+ ALU_FLAGS_MODIFIED(desc);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x18: // Fm = F3-0 * F7-4, Fa = F11-8 + F15-12
+ case 0x19: // Fm = F3-0 * F7-4, Fa = F11-8 - F15-12
+ case 0x1a: // Fm = F3-0 * F7-4, Fa = FLOAT F11-8 BY R15-12
+ case 0x1b: // Fm = F3-0 * F7-4, Fa = FIX F11-8 BY R15-12
+ case 0x1c: // Fm = F3-0 * F7-4, Fa = (F11-8 + F15-12) / 2
+ case 0x1e: // Fm = F3-0 * F7-4, Fa = MAX(F11-8, F15-12)
+ case 0x1f: // Fm = F3-0 * F7-4, Fa = MIN(F11-8, F15-12)
+ REG_USED(desc, fxm);
+ REG_USED(desc, fym);
+ REG_USED(desc, fxa);
+ REG_USED(desc, fya);
+ REG_MODIFIED(desc, fm);
+ REG_MODIFIED(desc, fa);
+ ALU_FLAGS_MODIFIED(desc);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x1d: // Fm = F3-0 * F7-4, Fa = ABS F11-8
+ REG_USED(desc, fxm);
+ REG_USED(desc, fym);
+ REG_USED(desc, fxa);
+ REG_MODIFIED(desc, fm);
+ REG_MODIFIED(desc, fa);
+ ALU_FLAGS_MODIFIED(desc);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+ // Rm = R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12, Rs = R11-8 - R15-12
+ REG_USED(desc, fxm);
+ REG_USED(desc, fym);
+ REG_USED(desc, fxa);
+ REG_USED(desc, fya);
+ REG_MODIFIED(desc, fm);
+ REG_MODIFIED(desc, fa);
+ REG_MODIFIED(desc, (opcode >> 16) & 0xf);
+ ALU_FLAGS_MODIFIED(desc);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+ case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+ // Fm = F3-0 * F7-4, Fa = F11-8 + F15-12, Fs = F11-8 - F15-12
+ REG_USED(desc, fxm);
+ REG_USED(desc, fym);
+ REG_USED(desc, fxa);
+ REG_USED(desc, fya);
+ REG_MODIFIED(desc, fm);
+ REG_MODIFIED(desc, fa);
+ REG_MODIFIED(desc, (opcode >> 16) & 0xf);
+ ALU_FLAGS_MODIFIED(desc);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ default:
+ fatalerror("sharc_frontend::describe_compute: unknown multiop %02X in opcode %04X%08X at %08X", multiop, (UINT16)(opcode >> 32), (UINT32)(opcode), desc.pc);
+ return false;
+ }
+ }
+ else // single-function operation
+ {
+ UINT32 operation = (opcode >> 12) & 0xff;
+
+ switch ((opcode >> 20) & 3)
+ {
+ case 0: // ALU operations
+ {
+ switch (operation)
+ {
+ case 0x01: // Rn = Rx + Ry
+ case 0x02: // Rn = Rx - Ry
+ case 0x09: // Rn = (Rx + Ry) / 2
+ case 0x40: // Rn = Rx AND Ry
+ case 0x41: // Rn = Rx OR Ry
+ case 0x42: // Rn = Rx XOR Ry
+ case 0x61: // Rn = MIN(Rx, Ry)
+ case 0x62: // Rn = MAX(Rx, Ry)
+ case 0x63: // Rn = CLIP Rx BY Ry
+ case 0x81: // Fn = Fx + Fy
+ case 0x82: // Fn = Fx - Fy
+ case 0x91: // Fn = ABS(Fx + Fy)
+ case 0x92: // Fn = ABS(Fx - Fy)
+ case 0x89: // Fn = (Fx + Fy) / 2
+ case 0xbd: // Fn = SCALB Fx BY Ry
+ case 0xd9: // Rn = FIX Fx BY Ry
+ case 0xdd: // Rn = TRUNC Fx BY Ry
+ case 0xda: // Fn = FLOAT Rx BY Ry
+ case 0xe1: // Fn = MIN(Fx, Fy)
+ case 0xe2: // Fn = MAX(Fx, Fy)
+ case 0xe3: // Fn = CLIP Fx BY Fy
+ case 0xe0: // Fn = Fx COPYSIGN Fy
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, rn);
+ ALU_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x05: // Rn = Rx + Ry + CI
+ case 0x06: // Rn = Rx - Ry + CI - 1
+ case 0x25: // Rn = Rx + CI
+ case 0x26: // Rn = Rx + CI - 1
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, rn);
+ AC_USED(desc);
+ ALU_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x0a: // COMP(Rx, Ry)
+ case 0x8a: // COMP(Fx, Fy)
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ ALU_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x29: // Rn = Rx + 1
+ case 0x2a: // Rn = Rx - 1
+ case 0x22: // Rn = -Rx
+ case 0x30: // Rn = ABS Rx
+ case 0x21: // Rn = PASS Rx
+ case 0x43: // Rn = NOT Rx
+ case 0xb0: // Fn = ABS(Fx)
+ case 0xa1: // Fn = PASS Fx
+ case 0xa2: // Fn = -Fx
+ case 0xa5: // Fn = RND Fx
+ case 0xad: // Rn = MANT Fx
+ case 0xc1: // Rn = LOGB Fx
+ case 0xc9: // Rn = FIX Fx
+ case 0xcd: // Rn = TRUNC Fx
+ case 0xca: // Fn = FLOAT Rx
+ case 0xc4: // Fn = RECIPS Fx
+ case 0xc5: // Fn = RSQRTS Fx
+ REG_USED(desc, rx);
+ REG_MODIFIED(desc, rn);
+ ALU_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
+ case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
+ {
+ /* Fixed-point Dual Add/Subtract */
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, rn);
+ REG_MODIFIED(desc, ra);
+ ALU_FLAGS_MODIFIED(desc);
+ break;
+ }
+
+ case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
+ case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
+ {
+ /* Floating-point Dual Add/Subtract */
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, rn);
+ REG_MODIFIED(desc, ra);
+ ALU_FLAGS_MODIFIED(desc);
+ break;
+ }
+
+ default:
+ fatalerror("sharc_frontend::describe_compute: unknown ALU op %02X in opcode %04X%08X at %08X", operation, (UINT16)(opcode >> 32), (UINT32)(opcode), desc.pc);
+ return false;
+ }
+ break;
+ }
+
+ case 1: // multiplier operations
+ {
+ switch (operation)
+ {
+ case 0x40: // Rn = Rx * Ry (UUI)
+ case 0x48: // Rn = Rx * Ry (UUF)
+ case 0x49: // Rn = Rx * Ry (UUFR)
+ case 0x50: // Rn = Rx * Ry (SUI)
+ case 0x58: // Rn = Rx * Ry (SUF)
+ case 0x59: // Rn = Rx * Ry (SUFR)
+ case 0x60: // Rn = Rx * Ry (USI)
+ case 0x68: // Rn = Rx * Ry (USF)
+ case 0x69: // Rn = Rx * Ry (USFR)
+ case 0x70: // Rn = Rx * Ry (SSI)
+ case 0x78: // Rn = Rx * Ry (SSF)
+ case 0x79: // Rn = Rx * Ry (SSFR)
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, rn);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x44: // MRF = Rx * Ry (UUI)
+ case 0x4c: // MRF = Rx * Ry (UUF)
+ case 0x4d: // MRF = Rx * Ry (UUFR)
+ case 0x54: // MRF = Rx * Ry (SUI)
+ case 0x5c: // MRF = Rx * Ry (SUF)
+ case 0x5d: // MRF = Rx * Ry (SUFR)
+ case 0x64: // MRF = Rx * Ry (USI)
+ case 0x6c: // MRF = Rx * Ry (USF)
+ case 0x6d: // MRF = Rx * Ry (USFR)
+ case 0x74: // MRF = Rx * Ry (SSI)
+ case 0x7c: // MRF = Rx * Ry (SSF)
+ case 0x7d: // MRF = Rx * Ry (SSFR)
+ // TODO: track MRF?
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x46: // MRB = Rx * Ry (UUI)
+ case 0x4e: // MRB = Rx * Ry (UUF)
+ case 0x4f: // MRB = Rx * Ry (UUFR)
+ case 0x56: // MRB = Rx * Ry (SUI)
+ case 0x5e: // MRB = Rx * Ry (SUF)
+ case 0x5f: // MRB = Rx * Ry (SUFR)
+ case 0x66: // MRB = Rx * Ry (USI)
+ case 0x6e: // MRB = Rx * Ry (USF)
+ case 0x6f: // MRB = Rx * Ry (USFR)
+ case 0x76: // MRB = Rx * Ry (SSI)
+ case 0x7e: // MRB = Rx * Ry (SSF)
+ case 0x7f: // MRB = Rx * Ry (SSFR)
+ // TODO: track MRB?
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x80: // Rn = MRF + Rx * Ry (UUI)
+ case 0x88: // Rn = MRF + Rx * Ry (UUF)
+ case 0x89: // Rn = MRF + Rx * Ry (UUFR)
+ case 0x90: // Rn = MRF + Rx * Ry (SUI)
+ case 0x98: // Rn = MRF + Rx * Ry (SUF)
+ case 0x99: // Rn = MRF + Rx * Ry (SUFR)
+ case 0xa0: // Rn = MRF + Rx * Ry (USI)
+ case 0xa8: // Rn = MRF + Rx * Ry (USF)
+ case 0xa9: // Rn = MRF + Rx * Ry (USFR)
+ case 0xb0: // Rn = MRF + Rx * Ry (SSI)
+ case 0xb8: // Rn = MRF + Rx * Ry (SSF)
+ case 0xb9: // Rn = MRF + Rx * Ry (SSFR)
+ // TODO: track MRF?
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, rn);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x82: // Rn = MRB + Rx * Ry (UUI)
+ case 0x8a: // Rn = MRB + Rx * Ry (UUF)
+ case 0x8b: // Rn = MRB + Rx * Ry (UUFR)
+ case 0x92: // Rn = MRB + Rx * Ry (SUI)
+ case 0x9a: // Rn = MRB + Rx * Ry (SUF)
+ case 0x9b: // Rn = MRB + Rx * Ry (SUFR)
+ case 0xa2: // Rn = MRB + Rx * Ry (USI)
+ case 0xaa: // Rn = MRB + Rx * Ry (USF)
+ case 0xab: // Rn = MRB + Rx * Ry (USFR)
+ case 0xb2: // Rn = MRB + Rx * Ry (SSI)
+ case 0xba: // Rn = MRB + Rx * Ry (SSF)
+ case 0xbb: // Rn = MRB + Rx * Ry (SSFR)
+ // TODO: track MRB?
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, rn);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x84: // MRF = MRF + Rx * Ry (UUI)
+ case 0x8c: // MRF = MRF + Rx * Ry (UUF)
+ case 0x8d: // MRF = MRF + Rx * Ry (UUFR)
+ case 0x94: // MRF = MRF + Rx * Ry (SUI)
+ case 0x9c: // MRF = MRF + Rx * Ry (SUF)
+ case 0x9d: // MRF = MRF + Rx * Ry (SUFR)
+ case 0xa4: // MRF = MRF + Rx * Ry (USI)
+ case 0xac: // MRF = MRF + Rx * Ry (USF)
+ case 0xad: // MRF = MRF + Rx * Ry (USFR)
+ case 0xb4: // MRF = MRF + Rx * Ry (SSI)
+ case 0xbc: // MRF = MRF + Rx * Ry (SSF)
+ case 0xbd: // MRF = MRF + Rx * Ry (SSFR)
+ // TODO: track MRF?
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x86: // MRB = MRB + Rx * Ry (UUI)
+ case 0x8e: // MRB = MRB + Rx * Ry (UUF)
+ case 0x8f: // MRB = MRB + Rx * Ry (UUFR)
+ case 0x96: // MRB = MRB + Rx * Ry (SUI)
+ case 0x9e: // MRB = MRB + Rx * Ry (SUF)
+ case 0x9f: // MRB = MRB + Rx * Ry (SUFR)
+ case 0xa6: // MRB = MRB + Rx * Ry (USI)
+ case 0xae: // MRB = MRB + Rx * Ry (USF)
+ case 0xaf: // MRB = MRB + Rx * Ry (USFR)
+ case 0xb6: // MRB = MRB + Rx * Ry (SSI)
+ case 0xbe: // MRB = MRB + Rx * Ry (SSF)
+ case 0xbf: // MRB = MRB + Rx * Ry (SSFR)
+ break;
+ // TODO: track MRB?
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0xc0: // Rn = MRF - Rx * Ry (UUI)
+ case 0xc8: // Rn = MRF - Rx * Ry (UUF)
+ case 0xc9: // Rn = MRF - Rx * Ry (UUFR)
+ case 0xd0: // Rn = MRF - Rx * Ry (SUI)
+ case 0xd8: // Rn = MRF - Rx * Ry (SUF)
+ case 0xd9: // Rn = MRF - Rx * Ry (SUFR)
+ case 0xe0: // Rn = MRF - Rx * Ry (USI)
+ case 0xe8: // Rn = MRF - Rx * Ry (USF)
+ case 0xe9: // Rn = MRF - Rx * Ry (USFR)
+ case 0xf0: // Rn = MRF - Rx * Ry (SSI)
+ case 0xf8: // Rn = MRF - Rx * Ry (SSF)
+ case 0xf9: // Rn = MRF - Rx * Ry (SSFR)
+ // TODO: track MRF?
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, rn);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0xc2: // Rn = MRB - Rx * Ry (UUI)
+ case 0xca: // Rn = MRB - Rx * Ry (UUF)
+ case 0xcb: // Rn = MRB - Rx * Ry (UUFR)
+ case 0xd2: // Rn = MRB - Rx * Ry (SUI)
+ case 0xda: // Rn = MRB - Rx * Ry (SUF)
+ case 0xdb: // Rn = MRB - Rx * Ry (SUFR)
+ case 0xe2: // Rn = MRB - Rx * Ry (USI)
+ case 0xea: // Rn = MRB - Rx * Ry (USF)
+ case 0xeb: // Rn = MRB - Rx * Ry (USFR)
+ case 0xf2: // Rn = MRB - Rx * Ry (SSI)
+ case 0xfa: // Rn = MRB - Rx * Ry (SSF)
+ case 0xfb: // Rn = MRB - Rx * Ry (SSFR)
+ // TODO: track MRB?
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, rn);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0xc4: // MRF = MRF - Rx * Ry (UUI)
+ case 0xcc: // MRF = MRF - Rx * Ry (UUF)
+ case 0xcd: // MRF = MRF - Rx * Ry (UUFR)
+ case 0xd4: // MRF = MRF - Rx * Ry (SUI)
+ case 0xdc: // MRF = MRF - Rx * Ry (SUF)
+ case 0xdd: // MRF = MRF - Rx * Ry (SUFR)
+ case 0xe4: // MRF = MRF - Rx * Ry (USI)
+ case 0xec: // MRF = MRF - Rx * Ry (USF)
+ case 0xed: // MRF = MRF - Rx * Ry (USFR)
+ case 0xf4: // MRF = MRF - Rx * Ry (SSI)
+ case 0xfc: // MRF = MRF - Rx * Ry (SSF)
+ case 0xfd: // MRF = MRF - Rx * Ry (SSFR)
+ // TODO: track MRF?
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0xc6: // MRB = MRB - Rx * Ry (UUI)
+ case 0xce: // MRB = MRB - Rx * Ry (UUF)
+ case 0xcf: // MRB = MRB - Rx * Ry (UUFR)
+ case 0xd6: // MRB = MRB - Rx * Ry (SUI)
+ case 0xde: // MRB = MRB - Rx * Ry (SUF)
+ case 0xdf: // MRB = MRB - Rx * Ry (SUFR)
+ case 0xe6: // MRB = MRB - Rx * Ry (USI)
+ case 0xee: // MRB = MRB - Rx * Ry (USF)
+ case 0xef: // MRB = MRB - Rx * Ry (USFR)
+ case 0xf6: // MRB = MRB - Rx * Ry (SSI)
+ case 0xfe: // MRB = MRB - Rx * Ry (SSF)
+ case 0xff: // MRB = MRB - Rx * Ry (SSFR)
+ // TODO: track MRB?
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x00: // Rn = SAT MRF (UI)
+ case 0x01: // Rn = SAT MRF (SI)
+ case 0x08: // Rn = SAT MRF (UF)
+ case 0x09: // Rn = SAT MRF (SF)
+ // TODO: track MRF?
+ REG_MODIFIED(desc, rn);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x02: // Rn = SAT MRB (UI)
+ case 0x03: // Rn = SAT MRB (SI)
+ case 0x0a: // Rn = SAT MRB (UF)
+ case 0x0b: // Rn = SAT MRB (SF)
+ // TODO: track MRB?
+ REG_MODIFIED(desc, rn);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x04: // MRF = SAT MRF (UI)
+ case 0x05: // MRF = SAT MRF (SI)
+ case 0x0c: // MRF = SAT MRF (UF)
+ case 0x0d: // MRF = SAT MRF (SF)
+ // TODO: track MRF?
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x06: // MRB = SAT MRB (UI)
+ case 0x07: // MRB = SAT MRB (SI)
+ case 0x0e: // MRB = SAT MRB (UF)
+ case 0x0f: // MRB = SAT MRB (SF)
+ // TODO: track MRB?
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x18: // Rn = RND MRF (U)
+ case 0x19: // Rn = RND MRF (S)
+ REG_MODIFIED(desc, rn);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x1a: // Rn = RND MRB (U)
+ case 0x1b: // Rn = RND MRB (S)
+ REG_MODIFIED(desc, rn);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x1c: // MRF = RND MRF (U)
+ case 0x1d: // MRF = RND MRF (S)
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x1e: // MRB = RND MRB (U)
+ case 0x1f: // MRB = RND MRB (S)
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x14: // MRF = 0
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+ case 0x16: // MRB = 0
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x30: // Fn = Fx * Fy
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, rn);
+ MULT_FLAGS_MODIFIED(desc);
+ break;
+
+ default:
+ fatalerror("sharc_frontend::describe_compute: unknown mult op %02X in opcode %04X%08X at %08X", operation, (UINT16)(opcode >> 32), (UINT32)(opcode), desc.pc);
+ }
+ break;
+ }
+
+ case 2: // shifter operations
+ {
+ switch (operation)
+ {
+ case 0x00: // Rn = LSHIFT Rx BY Ry | <data8>
+ case 0x04: // Rn = ASHIFT Rx BY Ry | <data8>
+ case 0x08: // Rn = ROT Rx BY Ry | <data8>
+ case 0xc4: // Rn = BCLR Rx BY Ry | <data8>
+ case 0xc0: // Rn = BSET Rx BY Ry | <data8>
+ case 0x44: // Rn = FDEP Rx BY Ry | <bit6>:<len6>
+ case 0x4c: // Rn = FDEP Rx BY Ry | <bit6>:<len6> (SE)
+ case 0x40: // Rn = FEXT Rx BY Ry | <bit6>:<len6>
+ case 0x48: // Rn = FEXT Rx BY Ry | <bit6>:<len6> (SE)
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_MODIFIED(desc, rn);
+ SHIFT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x20: // Rn = Rn OR LSHIFT Rx BY Ry | <data8>
+ case 0x24: // Rn = Rn OR ASHIFT Rx BY Ry | <data8>
+ case 0x64: // Rn = Rn OR FDEP Rx BY Ry | <bit6>:<len6>
+ case 0x6c: // Rn = Rn OR FDEP Rx BY Ry | <bit6>:<len6> (SE)
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ REG_USED(desc, rn);
+ REG_MODIFIED(desc, rn);
+ SHIFT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0xcc: // BTST Rx BY Ry | <data8>
+ REG_USED(desc, rx);
+ REG_USED(desc, ry);
+ SHIFT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x80: // Rn = EXP Rx
+ case 0x84: // Rn = EXP Rx (EX)
+ case 0x88: // Rn = LEFTZ Rx
+ case 0x8c: // Rn = LEFTO Rx
+ case 0x90: // Rn = FPACK Fx
+ case 0x94: // Fn = FUNPACK Rx
+ REG_USED(desc, rx);
+ REG_MODIFIED(desc, rn);
+ SHIFT_FLAGS_MODIFIED(desc);
+ break;
+
+ default:
+ fatalerror("sharc_frontend::describe_compute: unknown shift op %02X in opcode %04X%08X at %08X", operation, (UINT16)(opcode >> 32), (UINT32)(opcode), desc.pc);
+ }
+ break;
+ }
+
+ default:
+ fatalerror("sharc_frontend::describe_compute: unknown operation type in opcode %04X%08X at %08X", (UINT16)(opcode >> 32), (UINT32)(opcode), desc.pc);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool sharc_frontend::describe_ureg_access(opcode_desc &desc, int reg, UREG_ACCESS access)
+{
+ switch (reg)
+ {
+ case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
+ case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
+ if (access == UREG_READ)
+ REG_USED(desc, reg);
+ else
+ REG_MODIFIED(desc, reg);
+ break;
+
+ case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
+ if (access == UREG_READ)
+ DM_I_USED(desc, reg & 7);
+ else
+ DM_I_MODIFIED(desc, reg & 7);
+ break;
+ case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ if (access == UREG_READ)
+ PM_I_USED(desc, reg & 7);
+ else
+ PM_I_MODIFIED(desc, reg & 7);
+ break;
+
+ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
+ if (access == UREG_READ)
+ DM_M_USED(desc, reg & 7);
+ else
+ DM_M_MODIFIED(desc, reg & 7);
+ break;
+ case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+ if (access == UREG_READ)
+ PM_M_USED(desc, reg & 7);
+ else
+ PM_M_MODIFIED(desc, reg & 7);
+ break;
+
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
+ if (access == UREG_READ)
+ DM_L_USED(desc, reg & 7);
+ else
+ DM_L_MODIFIED(desc, reg & 7);
+ break;
+ case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+ if (access == UREG_READ)
+ PM_L_USED(desc, reg & 7);
+ else
+ PM_L_MODIFIED(desc, reg & 7);
+ break;
+
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ if (access == UREG_READ)
+ DM_B_USED(desc, reg & 7);
+ else
+ DM_B_MODIFIED(desc, reg & 7);
+ break;
+ case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
+ if (access == UREG_READ)
+ PM_B_USED(desc, reg & 7);
+ else
+ PM_B_MODIFIED(desc, reg & 7);
+ break;
+
+ case 0x60: // FADDR
+ break;
+ case 0x61: // DADDR
+ break;
+ case 0x63: // PC
+ break;
+ case 0x64: // PCSTK
+ break;
+ case 0x65: // PCSTKP
+ break;
+ case 0x66: // LADDR
+ break;
+ case 0x67: // CURLCNTR
+ break;
+ case 0x68: // LCNTR
+ break;
+ case 0x70: // USTAT1
+ break;
+ case 0x71: // USTAT2
+ break;
+ case 0x79: // IRPTL
+ break;
+ case 0x7a: // MODE1
+ break;
+ case 0x7b: // MODE2
+ break;
+
+ case 0x7c: // ASTAT
+ if (access == UREG_READ)
+ {
+ AZ_USED(desc);
+ AN_USED(desc);
+ AV_USED(desc);
+ AC_USED(desc);
+ AS_USED(desc);
+ AI_USED(desc);
+ MN_USED(desc);
+ MV_USED(desc);
+ MU_USED(desc);
+ MI_USED(desc);
+ SV_USED(desc);
+ SZ_USED(desc);
+ SS_USED(desc);
+ BTF_USED(desc);
+ AF_USED(desc);
+ }
+ else
+ {
+ ALU_FLAGS_MODIFIED(desc);
+ MULT_FLAGS_MODIFIED(desc);
+ SHIFT_FLAGS_MODIFIED(desc);
+ BTF_MODIFIED(desc);
+ AF_MODIFIED(desc);
+ }
+ break;
+
+ case 0x7d: // IMASK
+ break;
+ case 0x7e: // STKY
+ break;
+ case 0x7f: // IMASKP
+ break;
+ case 0xdb: // PX
+ break;
+ case 0xdc: // PX1
+ break;
+ case 0xdd: // PX2
+ break;
+
+ default:
+ fatalerror("sharc_frontend::describe_ureg_access: unknown UREG %02X", reg);
+ return false;
+ }
+
+ return true;
+}
+
+bool sharc_frontend::describe_shiftop_imm(opcode_desc &desc, int shiftop, int rn, int rx)
+{
+ switch (shiftop)
+ {
+ case 0x00: // LSHIFT Rx BY <data8>
+ case 0x01: // ASHIFT Rx BY <data8>
+ case 0x02: // ROT Rx BY <data8>
+ case 0x10: // FEXT Rx BY <data8>
+ case 0x11: // FDEP Rx BY <data8>
+ case 0x12: // FEXT Rx BY <bit6>:<len6> (SE)
+ case 0x13: // FDEP Rx BY <bit6>:<len6> (SE)
+ case 0x30: // BSET Rx BY <data8>
+ case 0x31: // BCLR Rx By <data8>
+ case 0x32: // BTGL Rx BY <data8>
+ REG_USED(desc, rx);
+ REG_MODIFIED(desc, rn);
+ SHIFT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x08: // Rn = Rn OR LSHIFT Rx BY <data8>
+ case 0x19: // Rn = Rn OR FDEP Rx BY <bit6>:<len6>
+ case 0x1b: // Rn = Rn OR FDEP Rx BY <bit6>:<len6> (SE)
+ REG_USED(desc, rx);
+ REG_USED(desc, rn);
+ REG_MODIFIED(desc, rn);
+ SHIFT_FLAGS_MODIFIED(desc);
+ break;
+
+ case 0x33: // BTST Rx BY <data8>
+ REG_USED(desc, rx);
+ SHIFT_FLAGS_MODIFIED(desc);
+ break;
+
+ default:
+ fatalerror("sharc_frontend::describe_shiftop_imm: unknown op %02X at %08X", shiftop, desc.pc);
+ return false;
+ }
+
+ return true;
+}
+
+void sharc_frontend::describe_if_condition(opcode_desc &desc, int condition)
+{
+ switch (condition)
+ {
+ case 0x00: AZ_USED(desc); break; /* EQ */
+ case 0x01: AZ_USED(desc); AN_USED(desc); break; /* LT */
+ case 0x02: AZ_USED(desc); AN_USED(desc); break; /* LE */
+ case 0x03: AC_USED(desc); break; /* AC */
+ case 0x04: AV_USED(desc); break; /* AV */
+ case 0x05: MV_USED(desc); break; /* MV */
+ case 0x06: MN_USED(desc); break; /* MS */
+ case 0x07: SV_USED(desc); break; /* SV */
+ case 0x08: SZ_USED(desc); break; /* SZ */
+ case 0x0d: BTF_USED(desc); break; /* TF */
+ case 0x10: AZ_USED(desc); break; /* NOT EQUAL */
+ case 0x11: AZ_USED(desc); AN_USED(desc); break; /* GE */
+ case 0x12: AZ_USED(desc); AN_USED(desc); break; /* GT */
+ case 0x13: AC_USED(desc); break; /* NOT AC */
+ case 0x14: AV_USED(desc); break; /* NOT AV */
+ case 0x15: MV_USED(desc); break; /* NOT MV */
+ case 0x16: MN_USED(desc); break; /* NOT MS */
+ case 0x17: SV_USED(desc); break; /* NOT SV */
+ case 0x18: SZ_USED(desc); break; /* NOT SZ */
+ case 0x1d: BTF_USED(desc); break; /* NOT TF */
+ }
+} \ No newline at end of file
diff --git a/src/devices/cpu/sharc/sharcfe.h b/src/devices/cpu/sharc/sharcfe.h
new file mode 100644
index 00000000000..b383e122606
--- /dev/null
+++ b/src/devices/cpu/sharc/sharcfe.h
@@ -0,0 +1,81 @@
+// license:BSD-3-Clause
+// copyright-holders:Ville Linde
+
+/******************************************************************************
+
+ Front-end for SHARC recompiler
+
+******************************************************************************/
+
+#pragma once
+
+#include "sharc.h"
+#include "cpu/drcfe.h"
+
+#ifndef __SHARCFE_H__
+#define __SHARCFE_H__
+
+class sharc_frontend : public drc_frontend
+{
+public:
+ sharc_frontend(adsp21062_device *sharc, UINT32 window_start, UINT32 window_end, UINT32 max_sequence);
+ void flush();
+
+ enum UREG_ACCESS
+ {
+ UREG_READ,
+ UREG_WRITE
+ };
+
+ enum LOOP_TYPE
+ {
+ LOOP_TYPE_COUNTER,
+ LOOP_TYPE_CONDITIONAL
+ };
+
+ enum LOOP_ENTRY_TYPE
+ {
+ LOOP_ENTRY_START = 0x1,
+ LOOP_ENTRY_EVALUATION = 0x2,
+ LOOP_ENTRY_ASTAT_CHECK = 0x4,
+ };
+
+ struct LOOP_ENTRY
+ {
+ UINT16 entrytype;
+ UINT8 looptype;
+ UINT8 condition;
+ UINT32 start_pc;
+ };
+
+ struct LOOP_DESCRIPTOR
+ {
+ UINT32 start_pc;
+ UINT32 end_pc;
+ UINT32 astat_check_pc;
+ LOOP_TYPE type;
+ int condition;
+ };
+
+protected:
+ // required overrides
+ virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
+
+private:
+ bool describe_compute(opcode_desc &desc, UINT64 opcode);
+ bool describe_ureg_access(opcode_desc &desc, int reg, UREG_ACCESS access);
+ bool describe_shiftop_imm(opcode_desc &desc, int shiftop, int rn, int rx);
+ void describe_if_condition(opcode_desc &desc, int condition);
+
+ void insert_loop(const LOOP_DESCRIPTOR &loopdesc);
+ void add_loop_entry(UINT32 pc, UINT8 type, UINT32 start_pc, UINT8 looptype, UINT8 condition);
+ bool is_loop_evaluation(UINT32 pc);
+ bool is_loop_start(UINT32 pc);
+ bool is_astat_delay_check(UINT32 pc);
+
+ adsp21062_device *m_sharc;
+
+ std::unique_ptr<LOOP_ENTRY[]> m_loopmap;
+};
+
+#endif /* __SHARCFE_H__ */
diff --git a/src/devices/cpu/sharc/sharcmem.hxx b/src/devices/cpu/sharc/sharcmem.hxx
index 3427e0346b8..f48c1ba3608 100644
--- a/src/devices/cpu/sharc/sharcmem.hxx
+++ b/src/devices/cpu/sharc/sharcmem.hxx
@@ -20,12 +20,13 @@ UINT32 adsp21062_device::pm_read32(UINT32 address)
(m_internal_ram_block1[addr + 1]);
}
else {
- fatalerror("SHARC: PM Bus Read32 %08X at %08X\n", address, m_pc);
+ fatalerror("SHARC: PM Bus Read32 %08X at %08X\n", address, m_core->pc);
}
}
void adsp21062_device::pm_write32(UINT32 address, UINT32 data)
{
+// printf("PM Write32 %08X, %08X at %08X\n", data, address, m_core->pc);
if (address >= 0x20000 && address < 0x28000)
{
UINT32 addr = (address & 0x7fff) * 3;
@@ -44,7 +45,8 @@ void adsp21062_device::pm_write32(UINT32 address, UINT32 data)
return;
}
else {
- fatalerror("SHARC: PM Bus Write32 %08X, %08X at %08X\n", address, data, m_pc);
+ debugger_break(machine());
+ //fatalerror("SHARC: PM Bus Write32 %08X, %08X at %08X\n", address, data, m_core->pc);
}
}
@@ -68,7 +70,7 @@ UINT64 adsp21062_device::pm_read48(UINT32 address)
((UINT64)(m_internal_ram_block1[addr + 2]) << 0);
}
else {
- fatalerror("SHARC: PM Bus Read48 %08X at %08X\n", address, m_pc);
+ fatalerror("SHARC: PM Bus Read48 %08X at %08X\n", address, m_core->pc);
}
return 0;
@@ -76,6 +78,7 @@ UINT64 adsp21062_device::pm_read48(UINT32 address)
void adsp21062_device::pm_write48(UINT32 address, UINT64 data)
{
+// printf("PM Write48 %08X%08X, %08X at %08X\n", (UINT32)(data >> 32), (UINT32)(data), address, m_core->pc);
if ((address >= 0x20000 && address < 0x28000))
{
UINT32 addr = (address & 0x7fff) * 3;
@@ -96,7 +99,7 @@ void adsp21062_device::pm_write48(UINT32 address, UINT64 data)
return;
}
else {
- fatalerror("SHARC: PM Bus Write48 %08X, %04X%08X at %08X\n", address, (UINT16)(data >> 32),(UINT32)data, m_pc);
+ fatalerror("SHARC: PM Bus Write48 %08X, %04X%08X at %08X\n", address, (UINT16)(data >> 32),(UINT32)data, m_core->pc);
}
}
@@ -128,7 +131,7 @@ UINT32 adsp21062_device::dm_read32(UINT32 address)
UINT32 addr = address & 0xffff;
UINT16 r = m_internal_ram_block0[addr ^ 1];
- if (m_mode1 & 0x4000)
+ if (m_core->mode1 & 0x4000)
{
// sign-extend
return (INT32)(INT16)(r);
@@ -144,7 +147,7 @@ UINT32 adsp21062_device::dm_read32(UINT32 address)
UINT32 addr = address & 0xffff;
UINT16 r = m_internal_ram_block1[addr ^ 1];
- if (m_mode1 & 0x4000)
+ if (m_core->mode1 & 0x4000)
{
// sign-extend
return (INT32)(INT16)(r);
diff --git a/src/devices/cpu/sharc/sharcops.hxx b/src/devices/cpu/sharc/sharcops.hxx
index 5bcc9765f1c..0400319d10e 100644
--- a/src/devices/cpu/sharc/sharcops.hxx
+++ b/src/devices/cpu/sharc/sharcops.hxx
@@ -3,14 +3,14 @@
#define SIGN_EXTEND6(x) (((x) & 0x20) ? (0xffffffc0 | (x)) : (x))
#define SIGN_EXTEND24(x) (((x) & 0x800000) ? (0xff000000 | (x)) : (x))
-#define PM_REG_I(x) (m_dag2.i[x])
-#define PM_REG_M(x) (m_dag2.m[x])
-#define PM_REG_B(x) (m_dag2.b[x])
-#define PM_REG_L(x) (m_dag2.l[x])
-#define DM_REG_I(x) (m_dag1.i[x])
-#define DM_REG_M(x) (m_dag1.m[x])
-#define DM_REG_B(x) (m_dag1.b[x])
-#define DM_REG_L(x) (m_dag1.l[x])
+#define PM_REG_I(x) (m_core->dag2.i[x])
+#define PM_REG_M(x) (m_core->dag2.m[x])
+#define PM_REG_B(x) (m_core->dag2.b[x])
+#define PM_REG_L(x) (m_core->dag2.l[x])
+#define DM_REG_I(x) (m_core->dag1.i[x])
+#define DM_REG_M(x) (m_core->dag1.m[x])
+#define DM_REG_B(x) (m_core->dag1.b[x])
+#define DM_REG_L(x) (m_core->dag1.l[x])
// ASTAT flags
#define AZ 0x1 /* ALU result zero */
@@ -33,44 +33,6 @@
#define FLG2 0x200000 /* FLAG2 */
#define FLG3 0x400000 /* FLAG3 */
-// STKY flags
-#define AUS 0x1 /* ALU floating-point underflow */
-#define AVS 0x2 /* ALU floating-point overflow */
-#define AOS 0x4 /* ALU fixed-point overflow */
-#define AIS 0x20 /* ALU floating-point invalid operation */
-
-// MODE1 flags
-#define MODE1_BR8 0x1 /* Bit-reverse for I8 */
-#define MODE1_BR0 0x2 /* Bit-reverse for I0 */
-#define MODE1_SRCU 0x4 /* Alternate register select for computational units */
-#define MODE1_SRD1H 0x8 /* DAG alternate register select (7-4) */
-#define MODE1_SRD1L 0x10 /* DAG alternate register select (3-0) */
-#define MODE1_SRD2H 0x20 /* DAG alternate register select (15-12) */
-#define MODE1_SRD2L 0x40 /* DAG alternate register select (11-8) */
-#define MODE1_SRRFH 0x80 /* Register file alternate select for R(15-8) */
-#define MODE1_SRRFL 0x400 /* Register file alternate select for R(7-0) */
-#define MODE1_NESTM 0x800 /* Interrupt nesting enable */
-#define MODE1_IRPTEN 0x1000 /* Global interrupt enable */
-#define MODE1_ALUSAT 0x2000 /* Enable ALU fixed-point saturation */
-#define MODE1_SSE 0x4000 /* Enable short word sign extension */
-#define MODE1_TRUNCATE 0x8000 /* (1) Floating-point truncation / (0) round to nearest */
-#define MODE1_RND32 0x10000 /* (1) 32-bit floating-point rounding / (0) 40-bit rounding */
-#define MODE1_CSEL 0x60000 /* CSelect */
-
-// MODE2 flags
-#define MODE2_IRQ0E 0x1 /* IRQ0 (1) Edge sens. / (0) Level sens. */
-#define MODE2_IRQ1E 0x2 /* IRQ1 (1) Edge sens. / (0) Level sens. */
-#define MODE2_IRQ2E 0x4 /* IRQ2 (1) Edge sens. / (0) Level sens. */
-#define MODE2_CADIS 0x10 /* Cache disable */
-#define MODE2_TIMEN 0x20 /* Timer enable */
-#define MODE2_BUSLK 0x40 /* External bus lock */
-#define MODE2_FLG0O 0x8000 /* FLAG0 (1) Output / (0) Input */
-#define MODE2_FLG1O 0x10000 /* FLAG1 (1) Output / (0) Input */
-#define MODE2_FLG2O 0x20000 /* FLAG2 (1) Output / (0) Input */
-#define MODE2_FLG3O 0x40000 /* FLAG3 (1) Output / (0) Input */
-#define MODE2_CAFRZ 0x80000 /* Cache freeze */
-
-
#define REG_PC 0x63
#define REG_PCSTK 0x64
#define REG_PCSTKP 0x65
@@ -89,8 +51,8 @@
-#define REG(x) (m_r[x].r)
-#define FREG(x) (m_r[x].f)
+#define REG(x) (m_core->r[x].r)
+#define FREG(x) (m_core->r[x].f)
#define UPDATE_CIRCULAR_BUFFER_PM(x) \
{ \
@@ -127,16 +89,16 @@
void adsp21062_device::add_systemreg_write_latency_effect(int sysreg, UINT32 data, UINT32 prev_data)
{
- if (m_systemreg_latency_cycles > 0)
+ if (m_core->systemreg_latency_cycles > 0)
{
- //fatalerror("SHARC: add_systemreg_write_latency_effect: already scheduled! (reg: %02X, data: %08X, PC: %08X)\n", systemreg_latency_reg, systemreg_latency_data, m_pc);
+ //fatalerror("SHARC: add_systemreg_write_latency_effect: already scheduled! (reg: %02X, data: %08X, PC: %08X)\n", systemreg_latency_reg, systemreg_latency_data, m_core->pc);
systemreg_write_latency_effect();
}
- m_systemreg_latency_cycles = 2;
- m_systemreg_latency_reg = sysreg;
- m_systemreg_latency_data = data;
- m_systemreg_previous_data = prev_data;
+ m_core->systemreg_latency_cycles = 2;
+ m_core->systemreg_latency_reg = sysreg;
+ m_core->systemreg_latency_data = data;
+ m_core->systemreg_previous_data = prev_data;
}
void adsp21062_device::swap_register(UINT32 *a, UINT32 *b)
@@ -149,15 +111,15 @@ void adsp21062_device::swap_register(UINT32 *a, UINT32 *b)
void adsp21062_device::systemreg_write_latency_effect()
{
int i;
- UINT32 data = m_systemreg_latency_data;
- UINT32 old_data = m_systemreg_previous_data;
+ UINT32 data = m_core->systemreg_latency_data;
+ UINT32 old_data = m_core->systemreg_previous_data;
- switch(m_systemreg_latency_reg)
+ switch(m_core->systemreg_latency_reg)
{
case 0xb: /* MODE1 */
{
UINT32 oldreg = old_data;
- m_mode1 = data;
+ m_core->mode1 = data;
if ((data & 0x1) != (oldreg & 0x1))
{
@@ -174,96 +136,96 @@ void adsp21062_device::systemreg_write_latency_effect()
if ((data & 0x8) != (oldreg & 0x8)) /* Switch DAG1 7-4 */
{
- swap_register(&m_dag1.i[4], &m_dag1_alt.i[4]);
- swap_register(&m_dag1.i[5], &m_dag1_alt.i[5]);
- swap_register(&m_dag1.i[6], &m_dag1_alt.i[6]);
- swap_register(&m_dag1.i[7], &m_dag1_alt.i[7]);
- swap_register(&m_dag1.m[4], &m_dag1_alt.m[4]);
- swap_register(&m_dag1.m[5], &m_dag1_alt.m[5]);
- swap_register(&m_dag1.m[6], &m_dag1_alt.m[6]);
- swap_register(&m_dag1.m[7], &m_dag1_alt.m[7]);
- swap_register(&m_dag1.l[4], &m_dag1_alt.l[4]);
- swap_register(&m_dag1.l[5], &m_dag1_alt.l[5]);
- swap_register(&m_dag1.l[6], &m_dag1_alt.l[6]);
- swap_register(&m_dag1.l[7], &m_dag1_alt.l[7]);
- swap_register(&m_dag1.b[4], &m_dag1_alt.b[4]);
- swap_register(&m_dag1.b[5], &m_dag1_alt.b[5]);
- swap_register(&m_dag1.b[6], &m_dag1_alt.b[6]);
- swap_register(&m_dag1.b[7], &m_dag1_alt.b[7]);
+ swap_register(&m_core->dag1.i[4], &m_core->dag1_alt.i[4]);
+ swap_register(&m_core->dag1.i[5], &m_core->dag1_alt.i[5]);
+ swap_register(&m_core->dag1.i[6], &m_core->dag1_alt.i[6]);
+ swap_register(&m_core->dag1.i[7], &m_core->dag1_alt.i[7]);
+ swap_register(&m_core->dag1.m[4], &m_core->dag1_alt.m[4]);
+ swap_register(&m_core->dag1.m[5], &m_core->dag1_alt.m[5]);
+ swap_register(&m_core->dag1.m[6], &m_core->dag1_alt.m[6]);
+ swap_register(&m_core->dag1.m[7], &m_core->dag1_alt.m[7]);
+ swap_register(&m_core->dag1.l[4], &m_core->dag1_alt.l[4]);
+ swap_register(&m_core->dag1.l[5], &m_core->dag1_alt.l[5]);
+ swap_register(&m_core->dag1.l[6], &m_core->dag1_alt.l[6]);
+ swap_register(&m_core->dag1.l[7], &m_core->dag1_alt.l[7]);
+ swap_register(&m_core->dag1.b[4], &m_core->dag1_alt.b[4]);
+ swap_register(&m_core->dag1.b[5], &m_core->dag1_alt.b[5]);
+ swap_register(&m_core->dag1.b[6], &m_core->dag1_alt.b[6]);
+ swap_register(&m_core->dag1.b[7], &m_core->dag1_alt.b[7]);
}
if ((data & 0x10) != (oldreg & 0x10)) /* Switch DAG1 3-0 */
{
- swap_register(&m_dag1.i[0], &m_dag1_alt.i[0]);
- swap_register(&m_dag1.i[1], &m_dag1_alt.i[1]);
- swap_register(&m_dag1.i[2], &m_dag1_alt.i[2]);
- swap_register(&m_dag1.i[3], &m_dag1_alt.i[3]);
- swap_register(&m_dag1.m[0], &m_dag1_alt.m[0]);
- swap_register(&m_dag1.m[1], &m_dag1_alt.m[1]);
- swap_register(&m_dag1.m[2], &m_dag1_alt.m[2]);
- swap_register(&m_dag1.m[3], &m_dag1_alt.m[3]);
- swap_register(&m_dag1.l[0], &m_dag1_alt.l[0]);
- swap_register(&m_dag1.l[1], &m_dag1_alt.l[1]);
- swap_register(&m_dag1.l[2], &m_dag1_alt.l[2]);
- swap_register(&m_dag1.l[3], &m_dag1_alt.l[3]);
- swap_register(&m_dag1.b[0], &m_dag1_alt.b[0]);
- swap_register(&m_dag1.b[1], &m_dag1_alt.b[1]);
- swap_register(&m_dag1.b[2], &m_dag1_alt.b[2]);
- swap_register(&m_dag1.b[3], &m_dag1_alt.b[3]);
+ swap_register(&m_core->dag1.i[0], &m_core->dag1_alt.i[0]);
+ swap_register(&m_core->dag1.i[1], &m_core->dag1_alt.i[1]);
+ swap_register(&m_core->dag1.i[2], &m_core->dag1_alt.i[2]);
+ swap_register(&m_core->dag1.i[3], &m_core->dag1_alt.i[3]);
+ swap_register(&m_core->dag1.m[0], &m_core->dag1_alt.m[0]);
+ swap_register(&m_core->dag1.m[1], &m_core->dag1_alt.m[1]);
+ swap_register(&m_core->dag1.m[2], &m_core->dag1_alt.m[2]);
+ swap_register(&m_core->dag1.m[3], &m_core->dag1_alt.m[3]);
+ swap_register(&m_core->dag1.l[0], &m_core->dag1_alt.l[0]);
+ swap_register(&m_core->dag1.l[1], &m_core->dag1_alt.l[1]);
+ swap_register(&m_core->dag1.l[2], &m_core->dag1_alt.l[2]);
+ swap_register(&m_core->dag1.l[3], &m_core->dag1_alt.l[3]);
+ swap_register(&m_core->dag1.b[0], &m_core->dag1_alt.b[0]);
+ swap_register(&m_core->dag1.b[1], &m_core->dag1_alt.b[1]);
+ swap_register(&m_core->dag1.b[2], &m_core->dag1_alt.b[2]);
+ swap_register(&m_core->dag1.b[3], &m_core->dag1_alt.b[3]);
}
if ((data & 0x20) != (oldreg & 0x20)) /* Switch DAG2 15-12 */
{
- swap_register(&m_dag2.i[4], &m_dag2_alt.i[4]);
- swap_register(&m_dag2.i[5], &m_dag2_alt.i[5]);
- swap_register(&m_dag2.i[6], &m_dag2_alt.i[6]);
- swap_register(&m_dag2.i[7], &m_dag2_alt.i[7]);
- swap_register(&m_dag2.m[4], &m_dag2_alt.m[4]);
- swap_register(&m_dag2.m[5], &m_dag2_alt.m[5]);
- swap_register(&m_dag2.m[6], &m_dag2_alt.m[6]);
- swap_register(&m_dag2.m[7], &m_dag2_alt.m[7]);
- swap_register(&m_dag2.l[4], &m_dag2_alt.l[4]);
- swap_register(&m_dag2.l[5], &m_dag2_alt.l[5]);
- swap_register(&m_dag2.l[6], &m_dag2_alt.l[6]);
- swap_register(&m_dag2.l[7], &m_dag2_alt.l[7]);
- swap_register(&m_dag2.b[4], &m_dag2_alt.b[4]);
- swap_register(&m_dag2.b[5], &m_dag2_alt.b[5]);
- swap_register(&m_dag2.b[6], &m_dag2_alt.b[6]);
- swap_register(&m_dag2.b[7], &m_dag2_alt.b[7]);
+ swap_register(&m_core->dag2.i[4], &m_core->dag2_alt.i[4]);
+ swap_register(&m_core->dag2.i[5], &m_core->dag2_alt.i[5]);
+ swap_register(&m_core->dag2.i[6], &m_core->dag2_alt.i[6]);
+ swap_register(&m_core->dag2.i[7], &m_core->dag2_alt.i[7]);
+ swap_register(&m_core->dag2.m[4], &m_core->dag2_alt.m[4]);
+ swap_register(&m_core->dag2.m[5], &m_core->dag2_alt.m[5]);
+ swap_register(&m_core->dag2.m[6], &m_core->dag2_alt.m[6]);
+ swap_register(&m_core->dag2.m[7], &m_core->dag2_alt.m[7]);
+ swap_register(&m_core->dag2.l[4], &m_core->dag2_alt.l[4]);
+ swap_register(&m_core->dag2.l[5], &m_core->dag2_alt.l[5]);
+ swap_register(&m_core->dag2.l[6], &m_core->dag2_alt.l[6]);
+ swap_register(&m_core->dag2.l[7], &m_core->dag2_alt.l[7]);
+ swap_register(&m_core->dag2.b[4], &m_core->dag2_alt.b[4]);
+ swap_register(&m_core->dag2.b[5], &m_core->dag2_alt.b[5]);
+ swap_register(&m_core->dag2.b[6], &m_core->dag2_alt.b[6]);
+ swap_register(&m_core->dag2.b[7], &m_core->dag2_alt.b[7]);
}
if ((data & 0x40) != (oldreg & 0x40)) /* Switch DAG2 11-8 */
{
- swap_register(&m_dag2.i[0], &m_dag2_alt.i[0]);
- swap_register(&m_dag2.i[1], &m_dag2_alt.i[1]);
- swap_register(&m_dag2.i[2], &m_dag2_alt.i[2]);
- swap_register(&m_dag2.i[3], &m_dag2_alt.i[3]);
- swap_register(&m_dag2.m[0], &m_dag2_alt.m[0]);
- swap_register(&m_dag2.m[1], &m_dag2_alt.m[1]);
- swap_register(&m_dag2.m[2], &m_dag2_alt.m[2]);
- swap_register(&m_dag2.m[3], &m_dag2_alt.m[3]);
- swap_register(&m_dag2.l[0], &m_dag2_alt.l[0]);
- swap_register(&m_dag2.l[1], &m_dag2_alt.l[1]);
- swap_register(&m_dag2.l[2], &m_dag2_alt.l[2]);
- swap_register(&m_dag2.l[3], &m_dag2_alt.l[3]);
- swap_register(&m_dag2.b[0], &m_dag2_alt.b[0]);
- swap_register(&m_dag2.b[1], &m_dag2_alt.b[1]);
- swap_register(&m_dag2.b[2], &m_dag2_alt.b[2]);
- swap_register(&m_dag2.b[3], &m_dag2_alt.b[3]);
+ swap_register(&m_core->dag2.i[0], &m_core->dag2_alt.i[0]);
+ swap_register(&m_core->dag2.i[1], &m_core->dag2_alt.i[1]);
+ swap_register(&m_core->dag2.i[2], &m_core->dag2_alt.i[2]);
+ swap_register(&m_core->dag2.i[3], &m_core->dag2_alt.i[3]);
+ swap_register(&m_core->dag2.m[0], &m_core->dag2_alt.m[0]);
+ swap_register(&m_core->dag2.m[1], &m_core->dag2_alt.m[1]);
+ swap_register(&m_core->dag2.m[2], &m_core->dag2_alt.m[2]);
+ swap_register(&m_core->dag2.m[3], &m_core->dag2_alt.m[3]);
+ swap_register(&m_core->dag2.l[0], &m_core->dag2_alt.l[0]);
+ swap_register(&m_core->dag2.l[1], &m_core->dag2_alt.l[1]);
+ swap_register(&m_core->dag2.l[2], &m_core->dag2_alt.l[2]);
+ swap_register(&m_core->dag2.l[3], &m_core->dag2_alt.l[3]);
+ swap_register(&m_core->dag2.b[0], &m_core->dag2_alt.b[0]);
+ swap_register(&m_core->dag2.b[1], &m_core->dag2_alt.b[1]);
+ swap_register(&m_core->dag2.b[2], &m_core->dag2_alt.b[2]);
+ swap_register(&m_core->dag2.b[3], &m_core->dag2_alt.b[3]);
}
if ((data & 0x80) != (oldreg & 0x80))
{
for (i=8; i<16; i++)
- swap_register((UINT32*)&m_r[i].r, (UINT32*)&m_reg_alt[i].r);
+ swap_register((UINT32*)&m_core->r[i].r, (UINT32*)&m_core->reg_alt[i].r);
}
if ((data & 0x400) != (oldreg & 0x400))
{
for (i=0; i<8; i++)
- swap_register((UINT32*)&m_r[i].r, (UINT32*)&m_reg_alt[i].r);
+ swap_register((UINT32*)&m_core->r[i].r, (UINT32*)&m_core->reg_alt[i].r);
}
break;
}
- default: fatalerror("SHARC: systemreg_latency_op: unknown register %02X at %08X\n", m_systemreg_latency_reg, m_pc);
+ default: fatalerror("SHARC: systemreg_latency_op: unknown register %02X at %08X\n", m_core->systemreg_latency_reg, m_core->pc);
}
- m_systemreg_latency_reg = -1;
+ m_core->systemreg_latency_reg = -1;
}
UINT32 adsp21062_device::GET_UREG(int ureg)
@@ -273,18 +235,18 @@ UINT32 adsp21062_device::GET_UREG(int ureg)
{
case 0x0: /* R0 - R15 */
{
- return m_r[reg].r;
+ return m_core->r[reg].r;
}
case 0x1:
{
if (reg & 0x8) /* I8 - I15 */
{
- return m_dag2.i[reg & 0x7];
+ return m_core->dag2.i[reg & 0x7];
}
else /* I0 - I7 */
{
- return m_dag1.i[reg & 0x7];
+ return m_core->dag1.i[reg & 0x7];
}
}
@@ -292,14 +254,14 @@ UINT32 adsp21062_device::GET_UREG(int ureg)
{
if (reg & 0x8) /* M8 - M15 */
{
- INT32 r = m_dag2.m[reg & 0x7];
+ INT32 r = m_core->dag2.m[reg & 0x7];
if (r & 0x800000) r |= 0xff000000;
return r;
}
else /* M0 - M7 */
{
- return m_dag1.m[reg & 0x7];
+ return m_core->dag1.m[reg & 0x7];
}
}
@@ -307,11 +269,11 @@ UINT32 adsp21062_device::GET_UREG(int ureg)
{
if (reg & 0x8) /* L8 - L15 */
{
- return m_dag2.l[reg & 0x7];
+ return m_core->dag2.l[reg & 0x7];
}
else /* L0 - L7 */
{
- return m_dag1.l[reg & 0x7];
+ return m_core->dag1.l[reg & 0x7];
}
}
@@ -319,11 +281,11 @@ UINT32 adsp21062_device::GET_UREG(int ureg)
{
if (reg & 0x8) /* B8 - B15 */
{
- return m_dag2.b[reg & 0x7];
+ return m_core->dag2.b[reg & 0x7];
}
else /* B0 - B7 */
{
- return m_dag1.b[reg & 0x7];
+ return m_core->dag1.b[reg & 0x7];
}
}
@@ -331,8 +293,8 @@ UINT32 adsp21062_device::GET_UREG(int ureg)
{
switch(reg)
{
- case 0x4: return m_pcstack[m_pcstkp]; /* PCSTK */
- default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_pc);
+ case 0x4: return m_core->pcstack[m_core->pcstkp]; /* PCSTK */
+ default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
}
break;
}
@@ -341,24 +303,24 @@ UINT32 adsp21062_device::GET_UREG(int ureg)
{
switch(reg)
{
- case 0x0: return m_ustat1; /* USTAT1 */
- case 0x1: return m_ustat2; /* USTAT2 */
- case 0x9: return m_irptl; /* IRPTL */
- case 0xa: return m_mode2; /* MODE2 */
- case 0xb: return m_mode1; /* MODE1 */
+ case 0x0: return m_core->ustat1; /* USTAT1 */
+ case 0x1: return m_core->ustat2; /* USTAT2 */
+ case 0x9: return m_core->irptl; /* IRPTL */
+ case 0xa: return m_core->mode2; /* MODE2 */
+ case 0xb: return m_core->mode1; /* MODE1 */
case 0xc: /* ASTAT */
{
- UINT32 r = m_astat;
+ UINT32 r = m_core->astat;
r &= ~0x00780000;
- r |= (m_flag[0] << 19);
- r |= (m_flag[1] << 20);
- r |= (m_flag[2] << 21);
- r |= (m_flag[3] << 22);
+ r |= (m_core->flag[0] << 19);
+ r |= (m_core->flag[1] << 20);
+ r |= (m_core->flag[2] << 21);
+ r |= (m_core->flag[3] << 22);
return r;
}
- case 0xd: return m_imask; /* IMASK */
- case 0xe: return m_stky; /* STKY */
- default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_pc);
+ case 0xd: return m_core->imask; /* IMASK */
+ case 0xe: return m_core->stky; /* STKY */
+ default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
}
break;
}
@@ -368,15 +330,15 @@ UINT32 adsp21062_device::GET_UREG(int ureg)
switch(reg)
{
/* PX needs to be handled separately if the whole 48 bits are needed */
- case 0xb: return (UINT32)(m_px); /* PX */
- case 0xc: return (UINT16)(m_px); /* PX1 */
- case 0xd: return (UINT32)(m_px >> 16); /* PX2 */
- default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_pc);
+ case 0xb: return (UINT32)(m_core->px); /* PX */
+ case 0xc: return (UINT16)(m_core->px); /* PX1 */
+ case 0xd: return (UINT32)(m_core->px >> 16); /* PX2 */
+ default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
}
break;
}
- default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_pc);
+ default: fatalerror("SHARC: GET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
}
}
@@ -386,39 +348,39 @@ void adsp21062_device::SET_UREG(int ureg, UINT32 data)
switch((ureg >> 4) & 0xf)
{
case 0x0: /* R0 - R15 */
- m_r[reg].r = data;
+ m_core->r[reg].r = data;
break;
case 0x1:
if (reg & 0x8) /* I8 - I15 */
{
- m_dag2.i[reg & 0x7] = data;
+ m_core->dag2.i[reg & 0x7] = data;
}
else /* I0 - I7 */
{
- m_dag1.i[reg & 0x7] = data;
+ m_core->dag1.i[reg & 0x7] = data;
}
break;
case 0x2:
if (reg & 0x8) /* M8 - M15 */
{
- m_dag2.m[reg & 0x7] = data;
+ m_core->dag2.m[reg & 0x7] = data;
}
else /* M0 - M7 */
{
- m_dag1.m[reg & 0x7] = data;
+ m_core->dag1.m[reg & 0x7] = data;
}
break;
case 0x3:
if (reg & 0x8) /* L8 - L15 */
{
- m_dag2.l[reg & 0x7] = data;
+ m_core->dag2.l[reg & 0x7] = data;
}
else /* L0 - L7 */
{
- m_dag1.l[reg & 0x7] = data;
+ m_core->dag1.l[reg & 0x7] = data;
}
break;
@@ -426,73 +388,73 @@ void adsp21062_device::SET_UREG(int ureg, UINT32 data)
// Note: loading B also loads the same value in I
if (reg & 0x8) /* B8 - B15 */
{
- m_dag2.b[reg & 0x7] = data;
- m_dag2.i[reg & 0x7] = data;
+ m_core->dag2.b[reg & 0x7] = data;
+ m_core->dag2.i[reg & 0x7] = data;
}
else /* B0 - B7 */
{
- m_dag1.b[reg & 0x7] = data;
- m_dag1.i[reg & 0x7] = data;
+ m_core->dag1.b[reg & 0x7] = data;
+ m_core->dag1.i[reg & 0x7] = data;
}
break;
case 0x6:
switch (reg)
{
- case 0x5: m_pcstkp = data; break; /* PCSTKP */
- case 0x8: m_lcntr = data; break; /* LCNTR */
- default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_pc);
+ case 0x5: m_core->pcstkp = data; break; /* PCSTKP */
+ case 0x8: m_core->lcntr = data; break; /* LCNTR */
+ default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
}
break;
case 0x7: /* system regs */
switch(reg)
{
- case 0x0: m_ustat1 = data; break; /* USTAT1 */
- case 0x1: m_ustat2 = data; break; /* USTAT2 */
+ case 0x0: m_core->ustat1 = data; break; /* USTAT1 */
+ case 0x1: m_core->ustat2 = data; break; /* USTAT2 */
- case 0x9: m_irptl = data; break; /* IRPTL */
- case 0xa: m_mode2 = data; break; /* MODE2 */
+ case 0x9: m_core->irptl = data; break; /* IRPTL */
+ case 0xa: m_core->mode2 = data; break; /* MODE2 */
case 0xb: /* MODE1 */
{
- add_systemreg_write_latency_effect(reg, data, m_mode1);
- m_mode1 = data;
+ add_systemreg_write_latency_effect(reg, data, m_core->mode1);
+ m_core->mode1 = data;
break;
}
- case 0xc: m_astat = data; break; /* ASTAT */
+ case 0xc: m_core->astat = data; break; /* ASTAT */
case 0xd: /* IMASK */
{
check_interrupts();
- m_imask = data;
+ m_core->imask = data;
break;
}
- case 0xe: m_stky = data; break; /* STKY */
- default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_pc);
+ case 0xe: m_core->stky = data; break; /* STKY */
+ default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
}
break;
case 0xd:
switch(reg)
{
- case 0xc: m_px &= U64(0xffffffffffff0000); m_px |= (data & 0xffff); break; /* PX1 */
- case 0xd: m_px &= U64(0x000000000000ffff); m_px |= (UINT64)data << 16; break; /* PX2 */
- default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_pc);
+ case 0xc: m_core->px &= U64(0xffffffffffff0000); m_core->px |= (data & 0xffff); break; /* PX1 */
+ case 0xd: m_core->px &= U64(0x000000000000ffff); m_core->px |= (UINT64)data << 16; break; /* PX2 */
+ default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
}
break;
- default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_pc);
+ default: fatalerror("SHARC: SET_UREG: unknown register %08X at %08X\n", ureg, m_core->pc);
}
}
/*****************************************************************************/
-#define SET_FLAG_SV_LSHIFT(x, shift) if((x) & ((UINT32)0xffffffff << shift)) m_astat |= SV
-#define SET_FLAG_SV_RSHIFT(x, shift) if((x) & ((UINT32)0xffffffff >> shift)) m_astat |= SV
+#define SET_FLAG_SV_LSHIFT(x, shift) if((x) & ((UINT32)0xffffffff << shift)) m_core->astat |= SV
+#define SET_FLAG_SV_RSHIFT(x, shift) if((x) & ((UINT32)0xffffffff >> shift)) m_core->astat |= SV
-#define SET_FLAG_SZ(x) if((x) == 0) m_astat |= SZ
+#define SET_FLAG_SZ(x) if((x) == 0) m_core->astat |= SZ
#define MAKE_EXTRACT_MASK(start_bit, length) ((0xffffffff << start_bit) & (((UINT32)0xffffffff) >> (32 - (start_bit + length))))
@@ -502,7 +464,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
int bit = data & 0x3f;
int len = (data >> 6) & 0x3f;
- m_astat &= ~(SZ|SV|SS);
+ m_core->astat &= ~(SZ|SV|SS);
switch(shiftop)
{
@@ -514,7 +476,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
REG(rn) = (shift < 32) ? (REG(rx) << shift) : 0;
if (shift > 0)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
}
SET_FLAG_SZ(REG(rn));
@@ -532,7 +494,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
REG(rn) = (shift < 32) ? ((INT32)REG(rx) << shift) : 0;
if (shift > 0)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
}
SET_FLAG_SZ(REG(rn));
@@ -566,7 +528,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
r = (shift < 32) ? (REG(rx) << shift) : 0;
if (shift > 0)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
}
SET_FLAG_SZ(r);
@@ -583,7 +545,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
SET_FLAG_SZ(REG(rn));
if (bit+len > 32)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
break;
}
@@ -602,7 +564,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
SET_FLAG_SZ(REG(rn));
if (bit+len > 32)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
break;
}
@@ -618,7 +580,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
SET_FLAG_SZ(REG(rn));
if (bit+len > 32)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
break;
}
@@ -632,7 +594,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
SET_FLAG_SZ(REG(rn));
if (bit+len > 32)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
break;
}
@@ -646,7 +608,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
}
else
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
SET_FLAG_SZ(REG(rn));
break;
@@ -661,7 +623,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
}
else
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
SET_FLAG_SZ(REG(rn));
break;
@@ -676,7 +638,7 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
}
else
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
SET_FLAG_SZ(REG(rn));
break;
@@ -692,12 +654,12 @@ void adsp21062_device::SHIFT_OPERATION_IMM(int shiftop, int data, int rn, int rx
}
else
{
- m_astat |= SZ | SV;
+ m_core->astat |= SZ | SV;
}
break;
}
- default: fatalerror("SHARC: unimplemented shift operation %02X at %08X\n", shiftop, m_pc);
+ default: fatalerror("SHARC: unimplemented shift operation %02X at %08X\n", shiftop, m_core->pc);
}
}
@@ -795,7 +757,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
}
default:
- fatalerror("SHARC: compute: multi-function opcode %02X not implemented ! (%08X, %08X)\n", multiop, m_pc, opcode);
+ fatalerror("SHARC: compute: multi-function opcode %02X not implemented ! (%08X, %08X)\n", multiop, m_core->pc, opcode);
break;
}
}
@@ -863,7 +825,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
break;
}
- default: fatalerror("SHARC: compute: unimplemented ALU operation %02X (%08X, %08X)\n", op, m_pc, opcode);
+ default: fatalerror("SHARC: compute: unimplemented ALU operation %02X (%08X, %08X)\n", op, m_core->pc, opcode);
}
break;
}
@@ -874,8 +836,8 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
{
switch(op)
{
- case 0x14: m_mrf = 0; break;
- case 0x16: m_mrb = 0; break;
+ case 0x14: m_core->mrf = 0; break;
+ case 0x16: m_core->mrb = 0; break;
case 0x30: compute_fmul(rn, rx, ry); break;
case 0x40: compute_mul_uuin(rn, rx, ry); break;
@@ -885,7 +847,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
case 0xb2: REG(rn) = compute_mrb_plus_mul_ssin(rx, ry); break;
default:
- fatalerror("SHARC: compute: multiplier operation %02X not implemented ! (%08X, %08X)\n", op, m_pc, opcode);
+ fatalerror("SHARC: compute: multiplier operation %02X not implemented ! (%08X, %08X)\n", op, m_core->pc, opcode);
break;
}
break;
@@ -895,7 +857,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
/* Shifter operations */
case 2:
{
- m_astat &= ~(SZ|SV|SS);
+ m_core->astat &= ~(SZ|SV|SS);
op >>= 2;
switch(op)
@@ -912,7 +874,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
REG(rn) = (shift < 32) ? (REG(rx) << shift) : 0;
if (shift > 0)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
}
SET_FLAG_SZ(REG(rn));
@@ -935,7 +897,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
(((UINT32)REG(rx) >> (32-s)) & ((UINT32)(0xffffffff) >> (32-s)));
if (shift > 0)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
}
SET_FLAG_SZ(REG(rn));
@@ -951,7 +913,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
REG(rn) = REG(rn) | ((shift < 32) ? (REG(rx) << shift) : 0);
if (shift > 0)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
}
SET_FLAG_SZ(REG(rn));
@@ -968,7 +930,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
SET_FLAG_SZ(REG(rn));
if (bit+len > 32)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
break;
}
@@ -986,7 +948,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
SET_FLAG_SZ(REG(rn));
if (bit+len > 32)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
break;
}
@@ -1002,7 +964,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
SET_FLAG_SZ(REG(rn));
if (bit+len > 32)
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
break;
}
@@ -1017,7 +979,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
}
else
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
SET_FLAG_SZ(REG(rn));
break;
@@ -1033,7 +995,7 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
}
else
{
- m_astat |= SV;
+ m_core->astat |= SV;
}
SET_FLAG_SZ(REG(rn));
break;
@@ -1050,13 +1012,13 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
}
else
{
- m_astat |= SZ | SV;
+ m_core->astat |= SZ | SV;
}
break;
}
default:
- fatalerror("SHARC: compute: shift operation %02X not implemented ! (%08X, %08X)\n", op, m_pc, opcode);
+ fatalerror("SHARC: compute: shift operation %02X not implemented ! (%08X, %08X)\n", op, m_core->pc, opcode);
}
break;
}
@@ -1069,143 +1031,143 @@ void adsp21062_device::COMPUTE(UINT32 opcode)
void adsp21062_device::PUSH_PC(UINT32 pc)
{
- m_pcstkp++;
- if(m_pcstkp >= 32)
+ m_core->pcstkp++;
+ if(m_core->pcstkp >= 32)
{
fatalerror("SHARC: PC Stack overflow!\n");
}
- if (m_pcstkp == 0)
+ if (m_core->pcstkp == 0)
{
- m_stky |= 0x400000;
+ m_core->stky |= 0x400000;
}
else
{
- m_stky &= ~0x400000;
+ m_core->stky &= ~0x400000;
}
- m_pcstk = pc;
- m_pcstack[m_pcstkp] = pc;
+ m_core->pcstk = pc;
+ m_core->pcstack[m_core->pcstkp] = pc;
}
UINT32 adsp21062_device::POP_PC()
{
- m_pcstk = m_pcstack[m_pcstkp];
+ m_core->pcstk = m_core->pcstack[m_core->pcstkp];
- if(m_pcstkp == 0)
+ if(m_core->pcstkp == 0)
{
fatalerror("SHARC: PC Stack underflow!\n");
}
- m_pcstkp--;
+ m_core->pcstkp--;
- if (m_pcstkp == 0)
+ if (m_core->pcstkp == 0)
{
- m_stky |= 0x400000;
+ m_core->stky |= 0x400000;
}
else
{
- m_stky &= ~0x400000;
+ m_core->stky &= ~0x400000;
}
- return m_pcstk;
+ return m_core->pcstk;
}
UINT32 adsp21062_device::TOP_PC()
{
- return m_pcstack[m_pcstkp];
+ return m_core->pcstack[m_core->pcstkp];
}
void adsp21062_device::PUSH_LOOP(UINT32 addr, UINT32 code, UINT32 type, UINT32 count)
{
- m_lstkp++;
- if(m_lstkp >= 6)
+ m_core->lstkp++;
+ if(m_core->lstkp >= 6)
{
fatalerror("SHARC: Loop Stack overflow!\n");
}
- if (m_lstkp == 0)
+ if (m_core->lstkp == 0)
{
- m_stky |= 0x4000000;
+ m_core->stky |= 0x4000000;
}
else
{
- m_stky &= ~0x4000000;
+ m_core->stky &= ~0x4000000;
}
- m_lcstack[m_lstkp] = count;
- m_lastack[m_lstkp] = (type << 30) | (code << 24) | addr;
- m_curlcntr = count;
+ m_core->lcstack[m_core->lstkp] = count;
+ m_core->lastack[m_core->lstkp] = (type << 30) | (code << 24) | addr;
+ m_core->curlcntr = count;
- m_laddr.addr = addr;
- m_laddr.code = code;
- m_laddr.loop_type = type;
+ m_core->laddr.addr = addr;
+ m_core->laddr.code = code;
+ m_core->laddr.loop_type = type;
}
void adsp21062_device::POP_LOOP()
{
- if(m_lstkp == 0)
+ if(m_core->lstkp == 0)
{
fatalerror("SHARC: Loop Stack underflow!\n");
}
- m_lstkp--;
+ m_core->lstkp--;
- if (m_lstkp == 0)
+ if (m_core->lstkp == 0)
{
- m_stky |= 0x4000000;
+ m_core->stky |= 0x4000000;
}
else
{
- m_stky &= ~0x4000000;
+ m_core->stky &= ~0x4000000;
}
- m_curlcntr = m_lcstack[m_lstkp];
+ m_core->curlcntr = m_core->lcstack[m_core->lstkp];
- m_laddr.addr = m_lastack[m_lstkp] & 0xffffff;
- m_laddr.code = (m_lastack[m_lstkp] >> 24) & 0x1f;
- m_laddr.loop_type = (m_lastack[m_lstkp] >> 30) & 0x3;
+ m_core->laddr.addr = m_core->lastack[m_core->lstkp] & 0xffffff;
+ m_core->laddr.code = (m_core->lastack[m_core->lstkp] >> 24) & 0x1f;
+ m_core->laddr.loop_type = (m_core->lastack[m_core->lstkp] >> 30) & 0x3;
}
void adsp21062_device::PUSH_STATUS_STACK()
{
- m_status_stkp++;
- if (m_status_stkp >= 5)
+ m_core->status_stkp++;
+ if (m_core->status_stkp >= 5)
{
fatalerror("SHARC: Status stack overflow!\n");
}
- if (m_status_stkp == 0)
+ if (m_core->status_stkp == 0)
{
- m_stky |= 0x1000000;
+ m_core->stky |= 0x1000000;
}
else
{
- m_stky &= ~0x1000000;
+ m_core->stky &= ~0x1000000;
}
- m_status_stack[m_status_stkp].mode1 = GET_UREG(REG_MODE1);
- m_status_stack[m_status_stkp].astat = GET_UREG(REG_ASTAT);
+ m_core->status_stack[m_core->status_stkp].mode1 = GET_UREG(REG_MODE1);
+ m_core->status_stack[m_core->status_stkp].astat = GET_UREG(REG_ASTAT);
}
void adsp21062_device::POP_STATUS_STACK()
{
- SET_UREG(REG_MODE1, m_status_stack[m_status_stkp].mode1);
- SET_UREG(REG_ASTAT, m_status_stack[m_status_stkp].astat);
+ SET_UREG(REG_MODE1, m_core->status_stack[m_core->status_stkp].mode1);
+ SET_UREG(REG_ASTAT, m_core->status_stack[m_core->status_stkp].astat);
- m_status_stkp--;
- if (m_status_stkp < 0)
+ m_core->status_stkp--;
+ if (m_core->status_stkp < 0)
{
fatalerror("SHARC: Status stack underflow!\n");
}
- if (m_status_stkp == 0)
+ if (m_core->status_stkp == 0)
{
- m_stky |= 0x1000000;
+ m_core->stky |= 0x1000000;
}
else
{
- m_stky &= ~0x1000000;
+ m_core->stky &= ~0x1000000;
}
}
@@ -1213,36 +1175,36 @@ int adsp21062_device::IF_CONDITION_CODE(int cond)
{
switch(cond)
{
- case 0x00: return m_astat & AZ; /* EQ */
- case 0x01: return !(m_astat & AZ) && (m_astat & AN); /* LT */
- case 0x02: return (m_astat & AZ) || (m_astat & AN); /* LE */
- case 0x03: return (m_astat & AC); /* AC */
- case 0x04: return (m_astat & AV); /* AV */
- case 0x05: return (m_astat & MV); /* MV */
- case 0x06: return (m_astat & MN); /* MS */
- case 0x07: return (m_astat & SV); /* SV */
- case 0x08: return (m_astat & SZ); /* SZ */
- case 0x09: return (m_flag[0] != 0); /* FLAG0 */
- case 0x0a: return (m_flag[1] != 0); /* FLAG1 */
- case 0x0b: return (m_flag[2] != 0); /* FLAG2 */
- case 0x0c: return (m_flag[3] != 0); /* FLAG3 */
- case 0x0d: return (m_astat & BTF); /* TF */
+ case 0x00: return m_core->astat & AZ; /* EQ */
+ case 0x01: return !(m_core->astat & AZ) && (m_core->astat & AN); /* LT */
+ case 0x02: return (m_core->astat & AZ) || (m_core->astat & AN); /* LE */
+ case 0x03: return (m_core->astat & AC); /* AC */
+ case 0x04: return (m_core->astat & AV); /* AV */
+ case 0x05: return (m_core->astat & MV); /* MV */
+ case 0x06: return (m_core->astat & MN); /* MS */
+ case 0x07: return (m_core->astat & SV); /* SV */
+ case 0x08: return (m_core->astat & SZ); /* SZ */
+ case 0x09: return (m_core->flag[0] != 0); /* FLAG0 */
+ case 0x0a: return (m_core->flag[1] != 0); /* FLAG1 */
+ case 0x0b: return (m_core->flag[2] != 0); /* FLAG2 */
+ case 0x0c: return (m_core->flag[3] != 0); /* FLAG3 */
+ case 0x0d: return (m_core->astat & BTF); /* TF */
case 0x0e: return 0; /* BM */
- case 0x0f: return (m_curlcntr!=1); /* NOT LCE */
- case 0x10: return !(m_astat & AZ); /* NOT EQUAL */
- case 0x11: return (m_astat & AZ) || !(m_astat & AN); /* GE */
- case 0x12: return !(m_astat & AZ) && !(m_astat & AN); /* GT */
- case 0x13: return !(m_astat & AC); /* NOT AC */
- case 0x14: return !(m_astat & AV); /* NOT AV */
- case 0x15: return !(m_astat & MV); /* NOT MV */
- case 0x16: return !(m_astat & MN); /* NOT MS */
- case 0x17: return !(m_astat & SV); /* NOT SV */
- case 0x18: return !(m_astat & SZ); /* NOT SZ */
- case 0x19: return (m_flag[0] == 0); /* NOT FLAG0 */
- case 0x1a: return (m_flag[1] == 0); /* NOT FLAG1 */
- case 0x1b: return (m_flag[2] == 0); /* NOT FLAG2 */
- case 0x1c: return (m_flag[3] == 0); /* NOT FLAG3 */
- case 0x1d: return !(m_astat & BTF); /* NOT TF */
+ case 0x0f: return (m_core->curlcntr!=1); /* NOT LCE */
+ case 0x10: return !(m_core->astat & AZ); /* NOT EQUAL */
+ case 0x11: return (m_core->astat & AZ) || !(m_core->astat & AN); /* GE */
+ case 0x12: return !(m_core->astat & AZ) && !(m_core->astat & AN); /* GT */
+ case 0x13: return !(m_core->astat & AC); /* NOT AC */
+ case 0x14: return !(m_core->astat & AV); /* NOT AV */
+ case 0x15: return !(m_core->astat & MV); /* NOT MV */
+ case 0x16: return !(m_core->astat & MN); /* NOT MS */
+ case 0x17: return !(m_core->astat & SV); /* NOT SV */
+ case 0x18: return !(m_core->astat & SZ); /* NOT SZ */
+ case 0x19: return (m_core->flag[0] == 0); /* NOT FLAG0 */
+ case 0x1a: return (m_core->flag[1] == 0); /* NOT FLAG1 */
+ case 0x1b: return (m_core->flag[2] == 0); /* NOT FLAG2 */
+ case 0x1c: return (m_core->flag[3] == 0); /* NOT FLAG3 */
+ case 0x1d: return !(m_core->astat & BTF); /* NOT TF */
case 0x1e: return 1; /* NOT BM */
case 0x1f: return 1; /* TRUE */
}
@@ -1253,36 +1215,36 @@ int adsp21062_device::DO_CONDITION_CODE(int cond)
{
switch(cond)
{
- case 0x00: return m_astat & AZ; /* EQ */
- case 0x01: return !(m_astat & AZ) && (m_astat & AN); /* LT */
- case 0x02: return (m_astat & AZ) || (m_astat & AN); /* LE */
- case 0x03: return (m_astat & AC); /* AC */
- case 0x04: return (m_astat & AV); /* AV */
- case 0x05: return (m_astat & MV); /* MV */
- case 0x06: return (m_astat & MN); /* MS */
- case 0x07: return (m_astat & SV); /* SV */
- case 0x08: return (m_astat & SZ); /* SZ */
- case 0x09: return (m_flag[0] != 0); /* FLAG0 */
- case 0x0a: return (m_flag[1] != 0); /* FLAG1 */
- case 0x0b: return (m_flag[2] != 0); /* FLAG2 */
- case 0x0c: return (m_flag[3] != 0); /* FLAG3 */
- case 0x0d: return (m_astat & BTF); /* TF */
+ case 0x00: return m_core->astat & AZ; /* EQ */
+ case 0x01: return !(m_core->astat & AZ) && (m_core->astat & AN); /* LT */
+ case 0x02: return (m_core->astat & AZ) || (m_core->astat & AN); /* LE */
+ case 0x03: return (m_core->astat & AC); /* AC */
+ case 0x04: return (m_core->astat & AV); /* AV */
+ case 0x05: return (m_core->astat & MV); /* MV */
+ case 0x06: return (m_core->astat & MN); /* MS */
+ case 0x07: return (m_core->astat & SV); /* SV */
+ case 0x08: return (m_core->astat & SZ); /* SZ */
+ case 0x09: return (m_core->flag[0] != 0); /* FLAG0 */
+ case 0x0a: return (m_core->flag[1] != 0); /* FLAG1 */
+ case 0x0b: return (m_core->flag[2] != 0); /* FLAG2 */
+ case 0x0c: return (m_core->flag[3] != 0); /* FLAG3 */
+ case 0x0d: return (m_core->astat & BTF); /* TF */
case 0x0e: return 0; /* BM */
- case 0x0f: return (m_curlcntr==1); /* LCE */
- case 0x10: return !(m_astat & AZ); /* NOT EQUAL */
- case 0x11: return (m_astat & AZ) || !(m_astat & AN); /* GE */
- case 0x12: return !(m_astat & AZ) && !(m_astat & AN); /* GT */
- case 0x13: return !(m_astat & AC); /* NOT AC */
- case 0x14: return !(m_astat & AV); /* NOT AV */
- case 0x15: return !(m_astat & MV); /* NOT MV */
- case 0x16: return !(m_astat & MN); /* NOT MS */
- case 0x17: return !(m_astat & SV); /* NOT SV */
- case 0x18: return !(m_astat & SZ); /* NOT SZ */
- case 0x19: return (m_flag[0] == 0); /* NOT FLAG0 */
- case 0x1a: return (m_flag[1] == 0); /* NOT FLAG1 */
- case 0x1b: return (m_flag[2] == 0); /* NOT FLAG2 */
- case 0x1c: return (m_flag[3] == 0); /* NOT FLAG3 */
- case 0x1d: return !(m_astat & BTF); /* NOT TF */
+ case 0x0f: return (m_core->curlcntr==1); /* LCE */
+ case 0x10: return !(m_core->astat & AZ); /* NOT EQUAL */
+ case 0x11: return (m_core->astat & AZ) || !(m_core->astat & AN); /* GE */
+ case 0x12: return !(m_core->astat & AZ) && !(m_core->astat & AN); /* GT */
+ case 0x13: return !(m_core->astat & AC); /* NOT AC */
+ case 0x14: return !(m_core->astat & AV); /* NOT AV */
+ case 0x15: return !(m_core->astat & MV); /* NOT MV */
+ case 0x16: return !(m_core->astat & MN); /* NOT MS */
+ case 0x17: return !(m_core->astat & SV); /* NOT SV */
+ case 0x18: return !(m_core->astat & SZ); /* NOT SZ */
+ case 0x19: return (m_core->flag[0] == 0); /* NOT FLAG0 */
+ case 0x1a: return (m_core->flag[1] == 0); /* NOT FLAG1 */
+ case 0x1b: return (m_core->flag[2] == 0); /* NOT FLAG2 */
+ case 0x1c: return (m_core->flag[3] == 0); /* NOT FLAG3 */
+ case 0x1d: return !(m_core->astat & BTF); /* NOT TF */
case 0x1e: return 1; /* NOT BM */
case 0x1f: return 0; /* FALSE (FOREVER) */
}
@@ -1295,15 +1257,15 @@ int adsp21062_device::DO_CONDITION_CODE(int cond)
/* compute / dreg <-> DM / dreg <-> PM */
void adsp21062_device::sharcop_compute_dreg_dm_dreg_pm()
{
- int pm_dreg = (m_opcode >> 23) & 0xf;
- int pmm = (m_opcode >> 27) & 0x7;
- int pmi = (m_opcode >> 30) & 0x7;
- int dm_dreg = (m_opcode >> 33) & 0xf;
- int dmm = (m_opcode >> 38) & 0x7;
- int dmi = (m_opcode >> 41) & 0x7;
- int pmd = (m_opcode >> 37) & 0x1;
- int dmd = (m_opcode >> 44) & 0x1;
- int compute = m_opcode & 0x7fffff;
+ int pm_dreg = (m_core->opcode >> 23) & 0xf;
+ int pmm = (m_core->opcode >> 27) & 0x7;
+ int pmi = (m_core->opcode >> 30) & 0x7;
+ int dm_dreg = (m_core->opcode >> 33) & 0xf;
+ int dmm = (m_core->opcode >> 38) & 0x7;
+ int dmi = (m_core->opcode >> 41) & 0x7;
+ int pmd = (m_core->opcode >> 37) & 0x1;
+ int dmd = (m_core->opcode >> 44) & 0x1;
+ int compute = m_core->opcode & 0x7fffff;
/* due to parallelity issues, source DREGs must be saved */
/* because the compute operation may change them */
@@ -1348,8 +1310,8 @@ void adsp21062_device::sharcop_compute_dreg_dm_dreg_pm()
/* compute */
void adsp21062_device::sharcop_compute()
{
- int cond = (m_opcode >> 33) & 0x1f;
- int compute = m_opcode & 0x7fffff;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int compute = m_core->opcode & 0x7fffff;
if (IF_CONDITION_CODE(cond) && compute != 0)
{
@@ -1363,13 +1325,13 @@ void adsp21062_device::sharcop_compute()
/* compute / ureg <-> DM|PM, pre-modify */
void adsp21062_device::sharcop_compute_ureg_dmpm_premod()
{
- int i = (m_opcode >> 41) & 0x7;
- int m = (m_opcode >> 38) & 0x7;
- int cond = (m_opcode >> 33) & 0x1f;
- int g = (m_opcode >> 32) & 0x1;
- int d = (m_opcode >> 31) & 0x1;
- int ureg = (m_opcode >> 23) & 0xff;
- int compute = m_opcode & 0x7fffff;
+ int i = (m_core->opcode >> 41) & 0x7;
+ int m = (m_core->opcode >> 38) & 0x7;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int g = (m_core->opcode >> 32) & 0x1;
+ int d = (m_core->opcode >> 31) & 0x1;
+ int ureg = (m_core->opcode >> 23) & 0xff;
+ int compute = m_core->opcode & 0x7fffff;
if (IF_CONDITION_CODE(cond))
{
@@ -1388,7 +1350,7 @@ void adsp21062_device::sharcop_compute_ureg_dmpm_premod()
{
if (ureg == 0xdb) /* PX register access is always 48-bit */
{
- pm_write48(PM_REG_I(i)+PM_REG_M(m), m_px);
+ pm_write48(PM_REG_I(i)+PM_REG_M(m), m_core->px);
}
else
{
@@ -1399,7 +1361,7 @@ void adsp21062_device::sharcop_compute_ureg_dmpm_premod()
{
if (ureg == 0xdb) /* PX register access is always 48-bit */
{
- m_px = pm_read48(PM_REG_I(i)+PM_REG_M(m));
+ m_core->px = pm_read48(PM_REG_I(i)+PM_REG_M(m));
}
else
{
@@ -1424,13 +1386,13 @@ void adsp21062_device::sharcop_compute_ureg_dmpm_premod()
/* compute / ureg <-> DM|PM, post-modify */
void adsp21062_device::sharcop_compute_ureg_dmpm_postmod()
{
- int i = (m_opcode >> 41) & 0x7;
- int m = (m_opcode >> 38) & 0x7;
- int cond = (m_opcode >> 33) & 0x1f;
- int g = (m_opcode >> 32) & 0x1;
- int d = (m_opcode >> 31) & 0x1;
- int ureg = (m_opcode >> 23) & 0xff;
- int compute = m_opcode & 0x7fffff;
+ int i = (m_core->opcode >> 41) & 0x7;
+ int m = (m_core->opcode >> 38) & 0x7;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int g = (m_core->opcode >> 32) & 0x1;
+ int d = (m_core->opcode >> 31) & 0x1;
+ int ureg = (m_core->opcode >> 23) & 0xff;
+ int compute = m_core->opcode & 0x7fffff;
if(IF_CONDITION_CODE(cond))
{
@@ -1449,7 +1411,7 @@ void adsp21062_device::sharcop_compute_ureg_dmpm_postmod()
{
if (ureg == 0xdb) /* PX register access is always 48-bit */
{
- pm_write48(PM_REG_I(i), m_px);
+ pm_write48(PM_REG_I(i), m_core->px);
}
else
{
@@ -1462,7 +1424,7 @@ void adsp21062_device::sharcop_compute_ureg_dmpm_postmod()
{
if (ureg == 0xdb) /* PX register access is always 48-bit */
{
- m_px = pm_read48(PM_REG_I(i));
+ m_core->px = pm_read48(PM_REG_I(i));
}
else
{
@@ -1496,12 +1458,12 @@ void adsp21062_device::sharcop_compute_ureg_dmpm_postmod()
/* compute / dreg <- DM, immediate modify */
void adsp21062_device::sharcop_compute_dm_to_dreg_immmod()
{
- int cond = (m_opcode >> 33) & 0x1f;
- int u = (m_opcode >> 38) & 0x1;
- int dreg = (m_opcode >> 23) & 0xf;
- int i = (m_opcode >> 41) & 0x7;
- int mod = SIGN_EXTEND6((m_opcode >> 27) & 0x3f);
- int compute = m_opcode & 0x7fffff;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int u = (m_core->opcode >> 38) & 0x1;
+ int dreg = (m_core->opcode >> 23) & 0xf;
+ int i = (m_core->opcode >> 41) & 0x7;
+ int mod = SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f);
+ int compute = m_core->opcode & 0x7fffff;
if (IF_CONDITION_CODE(cond))
{
@@ -1526,12 +1488,12 @@ void adsp21062_device::sharcop_compute_dm_to_dreg_immmod()
/* compute / dreg -> DM, immediate modify */
void adsp21062_device::sharcop_compute_dreg_to_dm_immmod()
{
- int cond = (m_opcode >> 33) & 0x1f;
- int u = (m_opcode >> 38) & 0x1;
- int dreg = (m_opcode >> 23) & 0xf;
- int i = (m_opcode >> 41) & 0x7;
- int mod = SIGN_EXTEND6((m_opcode >> 27) & 0x3f);
- int compute = m_opcode & 0x7fffff;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int u = (m_core->opcode >> 38) & 0x1;
+ int dreg = (m_core->opcode >> 23) & 0xf;
+ int i = (m_core->opcode >> 41) & 0x7;
+ int mod = SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f);
+ int compute = m_core->opcode & 0x7fffff;
/* due to parallelity issues, source REG must be saved */
/* because the shift operation may change it */
@@ -1560,12 +1522,12 @@ void adsp21062_device::sharcop_compute_dreg_to_dm_immmod()
/* compute / dreg <- PM, immediate modify */
void adsp21062_device::sharcop_compute_pm_to_dreg_immmod()
{
- int cond = (m_opcode >> 33) & 0x1f;
- int u = (m_opcode >> 38) & 0x1;
- int dreg = (m_opcode >> 23) & 0xf;
- int i = (m_opcode >> 41) & 0x7;
- int mod = SIGN_EXTEND6((m_opcode >> 27) & 0x3f);
- int compute = m_opcode & 0x7fffff;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int u = (m_core->opcode >> 38) & 0x1;
+ int dreg = (m_core->opcode >> 23) & 0xf;
+ int i = (m_core->opcode >> 41) & 0x7;
+ int mod = SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f);
+ int compute = m_core->opcode & 0x7fffff;
if (IF_CONDITION_CODE(cond))
{
@@ -1590,12 +1552,12 @@ void adsp21062_device::sharcop_compute_pm_to_dreg_immmod()
/* compute / dreg -> PM, immediate modify */
void adsp21062_device::sharcop_compute_dreg_to_pm_immmod()
{
- int cond = (m_opcode >> 33) & 0x1f;
- int u = (m_opcode >> 38) & 0x1;
- int dreg = (m_opcode >> 23) & 0xf;
- int i = (m_opcode >> 41) & 0x7;
- int mod = SIGN_EXTEND6((m_opcode >> 27) & 0x3f);
- int compute = m_opcode & 0x7fffff;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int u = (m_core->opcode >> 38) & 0x1;
+ int dreg = (m_core->opcode >> 23) & 0xf;
+ int i = (m_core->opcode >> 41) & 0x7;
+ int mod = SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f);
+ int compute = m_core->opcode & 0x7fffff;
/* due to parallelity issues, source REG must be saved */
/* because the compute operation may change it */
@@ -1627,10 +1589,10 @@ void adsp21062_device::sharcop_compute_dreg_to_pm_immmod()
/* compute / ureg <-> ureg */
void adsp21062_device::sharcop_compute_ureg_to_ureg()
{
- int src_ureg = (m_opcode >> 36) & 0xff;
- int dst_ureg = (m_opcode >> 23) & 0xff;
- int cond = (m_opcode >> 31) & 0x1f;
- int compute = m_opcode & 0x7fffff;
+ int src_ureg = (m_core->opcode >> 36) & 0xff;
+ int dst_ureg = (m_core->opcode >> 23) & 0xff;
+ int cond = (m_core->opcode >> 31) & 0x1f;
+ int compute = m_core->opcode & 0x7fffff;
if (IF_CONDITION_CODE(cond))
{
@@ -1653,16 +1615,16 @@ void adsp21062_device::sharcop_compute_ureg_to_ureg()
/* immediate shift / dreg <-> DM|PM */
void adsp21062_device::sharcop_imm_shift_dreg_dmpm()
{
- int i = (m_opcode >> 41) & 0x7;
- int m = (m_opcode >> 38) & 0x7;
- int g = (m_opcode >> 32) & 0x1;
- int d = (m_opcode >> 31) & 0x1;
- int dreg = (m_opcode >> 23) & 0xf;
- int cond = (m_opcode >> 33) & 0x1f;
- int data = ((m_opcode >> 8) & 0xff) | ((m_opcode >> 19) & 0xf00);
- int shiftop = (m_opcode >> 16) & 0x3f;
- int rn = (m_opcode >> 4) & 0xf;
- int rx = (m_opcode & 0xf);
+ int i = (m_core->opcode >> 41) & 0x7;
+ int m = (m_core->opcode >> 38) & 0x7;
+ int g = (m_core->opcode >> 32) & 0x1;
+ int d = (m_core->opcode >> 31) & 0x1;
+ int dreg = (m_core->opcode >> 23) & 0xf;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int data = ((m_core->opcode >> 8) & 0xff) | ((m_core->opcode >> 19) & 0xf00);
+ int shiftop = (m_core->opcode >> 16) & 0x3f;
+ int rn = (m_core->opcode >> 4) & 0xf;
+ int rx = (m_core->opcode & 0xf);
if (IF_CONDITION_CODE(cond))
{
@@ -1711,11 +1673,11 @@ void adsp21062_device::sharcop_imm_shift_dreg_dmpm()
/* immediate shift */
void adsp21062_device::sharcop_imm_shift()
{
- int cond = (m_opcode >> 33) & 0x1f;
- int data = ((m_opcode >> 8) & 0xff) | ((m_opcode >> 19) & 0xf00);
- int shiftop = (m_opcode >> 16) & 0x3f;
- int rn = (m_opcode >> 4) & 0xf;
- int rx = (m_opcode & 0xf);
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int data = ((m_core->opcode >> 8) & 0xff) | ((m_core->opcode >> 19) & 0xf00);
+ int shiftop = (m_core->opcode >> 16) & 0x3f;
+ int rn = (m_core->opcode >> 4) & 0xf;
+ int rx = (m_core->opcode & 0xf);
if (IF_CONDITION_CODE(cond))
{
@@ -1729,11 +1691,11 @@ void adsp21062_device::sharcop_imm_shift()
/* compute / modify */
void adsp21062_device::sharcop_compute_modify()
{
- int cond = (m_opcode >> 33) & 0x1f;
- int compute = m_opcode & 0x7fffff;
- int g = (m_opcode >> 38) & 0x1;
- int m = (m_opcode >> 27) & 0x7;
- int i = (m_opcode >> 30) & 0x7;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int compute = m_core->opcode & 0x7fffff;
+ int g = (m_core->opcode >> 38) & 0x1;
+ int m = (m_core->opcode >> 27) & 0x7;
+ int i = (m_core->opcode >> 30) & 0x7;
if (IF_CONDITION_CODE(cond))
{
@@ -1761,22 +1723,22 @@ void adsp21062_device::sharcop_compute_modify()
/* direct call to absolute address */
void adsp21062_device::sharcop_direct_call()
{
- int j = (m_opcode >> 26) & 0x1;
- int cond = (m_opcode >> 33) & 0x1f;
- UINT32 address = m_opcode & 0xffffff;
+ int j = (m_core->opcode >> 26) & 0x1;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ UINT32 address = m_core->opcode & 0xffffff;
if (IF_CONDITION_CODE(cond))
{
if (j)
{
- //PUSH_PC(m_pc+3); /* 1 instruction + 2 delayed instructions */
- PUSH_PC(m_nfaddr); /* 1 instruction + 2 delayed instructions */
+ //PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
+ PUSH_PC(m_core->nfaddr); /* 1 instruction + 2 delayed instructions */
CHANGE_PC_DELAYED(address);
}
else
{
- //PUSH_PC(m_pc+1);
- PUSH_PC(m_daddr);
+ //PUSH_PC(m_core->pc+1);
+ PUSH_PC(m_core->daddr);
CHANGE_PC(address);
}
}
@@ -1785,11 +1747,11 @@ void adsp21062_device::sharcop_direct_call()
/* direct jump to absolute address */
void adsp21062_device::sharcop_direct_jump()
{
- int la = (m_opcode >> 38) & 0x1;
- int ci = (m_opcode >> 24) & 0x1;
- int j = (m_opcode >> 26) & 0x1;
- int cond = (m_opcode >> 33) & 0x1f;
- UINT32 address = m_opcode & 0xffffff;
+ int la = (m_core->opcode >> 38) & 0x1;
+ int ci = (m_core->opcode >> 24) & 0x1;
+ int j = (m_core->opcode >> 26) & 0x1;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ UINT32 address = m_core->opcode & 0xffffff;
if(IF_CONDITION_CODE(cond))
{
@@ -1797,13 +1759,13 @@ void adsp21062_device::sharcop_direct_jump()
if (ci)
{
// TODO: anything else?
- if (m_status_stkp > 0)
+ if (m_core->status_stkp > 0)
{
POP_STATUS_STACK();
}
- m_interrupt_active = 0;
- m_irptl &= ~(1 << m_active_irq_num);
+ m_core->interrupt_active = 0;
+ m_core->irptl &= ~(1 << m_core->active_irq_num);
}
if (la)
@@ -1829,21 +1791,21 @@ void adsp21062_device::sharcop_direct_jump()
/* direct call to relative address */
void adsp21062_device::sharcop_relative_call()
{
- int j = (m_opcode >> 26) & 0x1;
- int cond = (m_opcode >> 33) & 0x1f;
- UINT32 address = m_opcode & 0xffffff;
+ int j = (m_core->opcode >> 26) & 0x1;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ UINT32 address = m_core->opcode & 0xffffff;
if (IF_CONDITION_CODE(cond))
{
if (j)
{
- PUSH_PC(m_pc+3); /* 1 instruction + 2 delayed instructions */
- CHANGE_PC_DELAYED(m_pc + SIGN_EXTEND24(address));
+ PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
+ CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND24(address));
}
else
{
- PUSH_PC(m_pc+1);
- CHANGE_PC(m_pc + SIGN_EXTEND24(address));
+ PUSH_PC(m_core->pc+1);
+ CHANGE_PC(m_core->pc + SIGN_EXTEND24(address));
}
}
}
@@ -1851,11 +1813,11 @@ void adsp21062_device::sharcop_relative_call()
/* direct jump to relative address */
void adsp21062_device::sharcop_relative_jump()
{
- int la = (m_opcode >> 38) & 0x1;
- int ci = (m_opcode >> 24) & 0x1;
- int j = (m_opcode >> 26) & 0x1;
- int cond = (m_opcode >> 33) & 0x1f;
- UINT32 address = m_opcode & 0xffffff;
+ int la = (m_core->opcode >> 38) & 0x1;
+ int ci = (m_core->opcode >> 24) & 0x1;
+ int j = (m_core->opcode >> 26) & 0x1;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ UINT32 address = m_core->opcode & 0xffffff;
if (IF_CONDITION_CODE(cond))
{
@@ -1863,13 +1825,13 @@ void adsp21062_device::sharcop_relative_jump()
if (ci)
{
// TODO: anything else?
- if (m_status_stkp > 0)
+ if (m_core->status_stkp > 0)
{
POP_STATUS_STACK();
}
- m_interrupt_active = 0;
- m_irptl &= ~(1 << m_active_irq_num);
+ m_core->interrupt_active = 0;
+ m_core->irptl &= ~(1 << m_core->active_irq_num);
}
if (la)
@@ -1880,11 +1842,11 @@ void adsp21062_device::sharcop_relative_jump()
if (j)
{
- CHANGE_PC_DELAYED(m_pc + SIGN_EXTEND24(address));
+ CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND24(address));
}
else
{
- CHANGE_PC(m_pc + SIGN_EXTEND24(address));
+ CHANGE_PC(m_core->pc + SIGN_EXTEND24(address));
}
}
}
@@ -1895,26 +1857,26 @@ void adsp21062_device::sharcop_relative_jump()
/* indirect jump */
void adsp21062_device::sharcop_indirect_jump()
{
- int la = (m_opcode >> 38) & 0x1;
- int ci = (m_opcode >> 24) & 0x1;
- int j = (m_opcode >> 26) & 0x1;
- int e = (m_opcode >> 25) & 0x1;
- int pmi = (m_opcode >> 30) & 0x7;
- int pmm = (m_opcode >> 27) & 0x7;
- int cond = (m_opcode >> 33) & 0x1f;
- int compute = m_opcode & 0x7fffff;
+ int la = (m_core->opcode >> 38) & 0x1;
+ int ci = (m_core->opcode >> 24) & 0x1;
+ int j = (m_core->opcode >> 26) & 0x1;
+ int e = (m_core->opcode >> 25) & 0x1;
+ int pmi = (m_core->opcode >> 30) & 0x7;
+ int pmm = (m_core->opcode >> 27) & 0x7;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int compute = m_core->opcode & 0x7fffff;
// Clear Interrupt
if (ci)
{
// TODO: anything else?
- if (m_status_stkp > 0)
+ if (m_core->status_stkp > 0)
{
POP_STATUS_STACK();
}
- m_interrupt_active = 0;
- m_irptl &= ~(1 << m_active_irq_num);
+ m_core->interrupt_active = 0;
+ m_core->irptl &= ~(1 << m_core->active_irq_num);
}
if (e) /* IF...ELSE */
@@ -1974,12 +1936,12 @@ void adsp21062_device::sharcop_indirect_jump()
/* indirect call */
void adsp21062_device::sharcop_indirect_call()
{
- int j = (m_opcode >> 26) & 0x1;
- int e = (m_opcode >> 25) & 0x1;
- int pmi = (m_opcode >> 30) & 0x7;
- int pmm = (m_opcode >> 27) & 0x7;
- int cond = (m_opcode >> 33) & 0x1f;
- int compute = m_opcode & 0x7fffff;
+ int j = (m_core->opcode >> 26) & 0x1;
+ int e = (m_core->opcode >> 25) & 0x1;
+ int pmi = (m_core->opcode >> 30) & 0x7;
+ int pmm = (m_core->opcode >> 27) & 0x7;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int compute = m_core->opcode & 0x7fffff;
if (e) /* IF...ELSE */
{
@@ -1987,14 +1949,14 @@ void adsp21062_device::sharcop_indirect_call()
{
if (j)
{
- //PUSH_PC(m_pc+3); /* 1 instruction + 2 delayed instructions */
- PUSH_PC(m_nfaddr); /* 1 instruction + 2 delayed instructions */
+ //PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
+ PUSH_PC(m_core->nfaddr); /* 1 instruction + 2 delayed instructions */
CHANGE_PC_DELAYED(PM_REG_I(pmi) + PM_REG_M(pmm));
}
else
{
- //PUSH_PC(m_pc+1);
- PUSH_PC(m_daddr);
+ //PUSH_PC(m_core->pc+1);
+ PUSH_PC(m_core->daddr);
CHANGE_PC(PM_REG_I(pmi) + PM_REG_M(pmm));
}
}
@@ -2017,14 +1979,14 @@ void adsp21062_device::sharcop_indirect_call()
if (j)
{
- //PUSH_PC(m_pc+3); /* 1 instruction + 2 delayed instructions */
- PUSH_PC(m_nfaddr); /* 1 instruction + 2 delayed instructions */
+ //PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
+ PUSH_PC(m_core->nfaddr); /* 1 instruction + 2 delayed instructions */
CHANGE_PC_DELAYED(PM_REG_I(pmi) + PM_REG_M(pmm));
}
else
{
- //PUSH_PC(m_pc+1);
- PUSH_PC(m_daddr);
+ //PUSH_PC(m_core->pc+1);
+ PUSH_PC(m_core->daddr);
CHANGE_PC(PM_REG_I(pmi) + PM_REG_M(pmm));
}
}
@@ -2037,24 +1999,24 @@ void adsp21062_device::sharcop_indirect_call()
/* indirect jump to relative address */
void adsp21062_device::sharcop_relative_jump_compute()
{
- int la = (m_opcode >> 38) & 0x1;
- int ci = (m_opcode >> 24) & 0x1;
- int j = (m_opcode >> 26) & 0x1;
- int e = (m_opcode >> 25) & 0x1;
- int cond = (m_opcode >> 33) & 0x1f;
- int compute = m_opcode & 0x7fffff;
+ int la = (m_core->opcode >> 38) & 0x1;
+ int ci = (m_core->opcode >> 24) & 0x1;
+ int j = (m_core->opcode >> 26) & 0x1;
+ int e = (m_core->opcode >> 25) & 0x1;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int compute = m_core->opcode & 0x7fffff;
// Clear Interrupt
if (ci)
{
// TODO: anything else?
- if (m_status_stkp > 0)
+ if (m_core->status_stkp > 0)
{
POP_STATUS_STACK();
}
- m_interrupt_active = 0;
- m_irptl &= ~(1 << m_active_irq_num);
+ m_core->interrupt_active = 0;
+ m_core->irptl &= ~(1 << m_core->active_irq_num);
}
if (e) /* IF...ELSE */
@@ -2069,11 +2031,11 @@ void adsp21062_device::sharcop_relative_jump_compute()
if (j)
{
- CHANGE_PC_DELAYED(m_pc + SIGN_EXTEND6((m_opcode >> 27) & 0x3f));
+ CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
}
else
{
- CHANGE_PC(m_pc + SIGN_EXTEND6((m_opcode >> 27) & 0x3f));
+ CHANGE_PC(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
}
}
else
@@ -2101,11 +2063,11 @@ void adsp21062_device::sharcop_relative_jump_compute()
if (j)
{
- CHANGE_PC_DELAYED(m_pc + SIGN_EXTEND6((m_opcode >> 27) & 0x3f));
+ CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
}
else
{
- CHANGE_PC(m_pc + SIGN_EXTEND6((m_opcode >> 27) & 0x3f));
+ CHANGE_PC(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
}
}
}
@@ -2114,10 +2076,10 @@ void adsp21062_device::sharcop_relative_jump_compute()
/* indirect call to relative address */
void adsp21062_device::sharcop_relative_call_compute()
{
- int j = (m_opcode >> 26) & 0x1;
- int e = (m_opcode >> 25) & 0x1;
- int cond = (m_opcode >> 33) & 0x1f;
- int compute = m_opcode & 0x7fffff;
+ int j = (m_core->opcode >> 26) & 0x1;
+ int e = (m_core->opcode >> 25) & 0x1;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int compute = m_core->opcode & 0x7fffff;
if (e) /* IF...ELSE */
{
@@ -2125,15 +2087,15 @@ void adsp21062_device::sharcop_relative_call_compute()
{
if (j)
{
- //PUSH_PC(m_pc+3); /* 1 instruction + 2 delayed instructions */
- PUSH_PC(m_nfaddr); /* 1 instruction + 2 delayed instructions */
- CHANGE_PC_DELAYED(m_pc + SIGN_EXTEND6((m_opcode >> 27) & 0x3f));
+ //PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
+ PUSH_PC(m_core->nfaddr); /* 1 instruction + 2 delayed instructions */
+ CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
}
else
{
- //PUSH_PC(m_pc+1);
- PUSH_PC(m_daddr);
- CHANGE_PC(m_pc + SIGN_EXTEND6((m_opcode >> 27) & 0x3f));
+ //PUSH_PC(m_core->pc+1);
+ PUSH_PC(m_core->daddr);
+ CHANGE_PC(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
}
}
else
@@ -2155,15 +2117,15 @@ void adsp21062_device::sharcop_relative_call_compute()
if (j)
{
- //PUSH_PC(m_pc+3); /* 1 instruction + 2 delayed instructions */
- PUSH_PC(m_nfaddr); /* 1 instruction + 2 delayed instructions */
- CHANGE_PC_DELAYED(m_pc + SIGN_EXTEND6((m_opcode >> 27) & 0x3f));
+ //PUSH_PC(m_core->pc+3); /* 1 instruction + 2 delayed instructions */
+ PUSH_PC(m_core->nfaddr); /* 1 instruction + 2 delayed instructions */
+ CHANGE_PC_DELAYED(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
}
else
{
- //PUSH_PC(m_pc+1);
- PUSH_PC(m_daddr);
- CHANGE_PC(m_pc + SIGN_EXTEND6((m_opcode >> 27) & 0x3f));
+ //PUSH_PC(m_core->pc+1);
+ PUSH_PC(m_core->daddr);
+ CHANGE_PC(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
}
}
}
@@ -2175,13 +2137,13 @@ void adsp21062_device::sharcop_relative_call_compute()
/* indirect jump / compute / dreg <-> DM */
void adsp21062_device::sharcop_indirect_jump_compute_dreg_dm()
{
- int d = (m_opcode >> 44) & 0x1;
- int dmi = (m_opcode >> 41) & 0x7;
- int dmm = (m_opcode >> 38) & 0x7;
- int pmi = (m_opcode >> 30) & 0x7;
- int pmm = (m_opcode >> 27) & 0x7;
- int cond = (m_opcode >> 33) & 0x1f;
- int dreg = (m_opcode >> 23) & 0xf;
+ int d = (m_core->opcode >> 44) & 0x1;
+ int dmi = (m_core->opcode >> 41) & 0x7;
+ int dmm = (m_core->opcode >> 38) & 0x7;
+ int pmi = (m_core->opcode >> 30) & 0x7;
+ int pmm = (m_core->opcode >> 27) & 0x7;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int dreg = (m_core->opcode >> 23) & 0xf;
if (IF_CONDITION_CODE(cond))
{
@@ -2189,7 +2151,7 @@ void adsp21062_device::sharcop_indirect_jump_compute_dreg_dm()
}
else
{
- UINT32 compute = m_opcode & 0x7fffff;
+ UINT32 compute = m_core->opcode & 0x7fffff;
/* due to parallelity issues, source REG must be saved */
/* because the compute operation may change it */
UINT32 parallel_dreg = REG(dreg);
@@ -2220,19 +2182,19 @@ void adsp21062_device::sharcop_indirect_jump_compute_dreg_dm()
/* relative jump / compute / dreg <-> DM */
void adsp21062_device::sharcop_relative_jump_compute_dreg_dm()
{
- int d = (m_opcode >> 44) & 0x1;
- int dmi = (m_opcode >> 41) & 0x7;
- int dmm = (m_opcode >> 38) & 0x7;
- int cond = (m_opcode >> 33) & 0x1f;
- int dreg = (m_opcode >> 23) & 0xf;
+ int d = (m_core->opcode >> 44) & 0x1;
+ int dmi = (m_core->opcode >> 41) & 0x7;
+ int dmm = (m_core->opcode >> 38) & 0x7;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int dreg = (m_core->opcode >> 23) & 0xf;
if (IF_CONDITION_CODE(cond))
{
- CHANGE_PC(m_pc + SIGN_EXTEND6((m_opcode >> 27) & 0x3f));
+ CHANGE_PC(m_core->pc + SIGN_EXTEND6((m_core->opcode >> 27) & 0x3f));
}
else
{
- UINT32 compute = m_opcode & 0x7fffff;
+ UINT32 compute = m_core->opcode & 0x7fffff;
/* due to parallelity issues, source REG must be saved */
/* because the compute operation may change it */
UINT32 parallel_dreg = REG(dreg);
@@ -2263,11 +2225,11 @@ void adsp21062_device::sharcop_relative_jump_compute_dreg_dm()
/* return from subroutine / compute */
void adsp21062_device::sharcop_rts()
{
- int cond = (m_opcode >> 33) & 0x1f;
- int j = (m_opcode >> 26) & 0x1;
- int e = (m_opcode >> 25) & 0x1;
- //int lr = (m_opcode >> 24) & 0x1;
- int compute = m_opcode & 0x7fffff;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int j = (m_core->opcode >> 26) & 0x1;
+ int e = (m_core->opcode >> 25) & 0x1;
+ //int lr = (m_core->opcode >> 24) & 0x1;
+ int compute = m_core->opcode & 0x7fffff;
//if(lr)
// fatalerror("SHARC: rts: loop reentry not implemented!\n");
@@ -2320,12 +2282,12 @@ void adsp21062_device::sharcop_rts()
/* return from interrupt / compute */
void adsp21062_device::sharcop_rti()
{
- int cond = (m_opcode >> 33) & 0x1f;
- int j = (m_opcode >> 26) & 0x1;
- int e = (m_opcode >> 25) & 0x1;
- int compute = m_opcode & 0x7fffff;
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int j = (m_core->opcode >> 26) & 0x1;
+ int e = (m_core->opcode >> 25) & 0x1;
+ int compute = m_core->opcode & 0x7fffff;
- m_irptl &= ~(1 << m_active_irq_num);
+ m_core->irptl &= ~(1 << m_core->active_irq_num);
if(e) /* IF...ELSE */
{
@@ -2368,12 +2330,12 @@ void adsp21062_device::sharcop_rti()
}
}
- if (m_status_stkp > 0)
+ if (m_core->status_stkp > 0)
{
POP_STATUS_STACK();
}
- m_interrupt_active = 0;
+ m_core->interrupt_active = 0;
check_interrupts();
}
@@ -2383,9 +2345,9 @@ void adsp21062_device::sharcop_rti()
/* do until counter expired, LCNTR immediate */
void adsp21062_device::sharcop_do_until_counter_imm()
{
- UINT16 data = (UINT16)(m_opcode >> 24);
- int offset = SIGN_EXTEND24(m_opcode & 0xffffff);
- UINT32 address = m_pc + offset;
+ UINT16 data = (UINT16)(m_core->opcode >> 24);
+ int offset = SIGN_EXTEND24(m_core->opcode & 0xffffff);
+ UINT32 address = m_core->pc + offset;
int type;
int cond = 0xf; /* until LCE (loop counter expired */
int distance = abs(offset);
@@ -2403,11 +2365,11 @@ void adsp21062_device::sharcop_do_until_counter_imm()
type = 3;
}
- m_lcntr = data;
- if (m_lcntr > 0)
+ m_core->lcntr = data;
+ if (m_core->lcntr > 0)
{
- PUSH_PC(m_pc+1);
- PUSH_LOOP(address, cond, type, m_lcntr);
+ PUSH_PC(m_core->pc+1);
+ PUSH_LOOP(address, cond, type, m_core->lcntr);
}
}
@@ -2417,9 +2379,9 @@ void adsp21062_device::sharcop_do_until_counter_imm()
/* do until counter expired, LCNTR from UREG */
void adsp21062_device::sharcop_do_until_counter_ureg()
{
- int ureg = (m_opcode >> 32) & 0xff;
- int offset = SIGN_EXTEND24(m_opcode & 0xffffff);
- UINT32 address = m_pc + offset;
+ int ureg = (m_core->opcode >> 32) & 0xff;
+ int offset = SIGN_EXTEND24(m_core->opcode & 0xffffff);
+ UINT32 address = m_core->pc + offset;
int type;
int cond = 0xf; /* until LCE (loop counter expired */
int distance = abs(offset);
@@ -2437,11 +2399,11 @@ void adsp21062_device::sharcop_do_until_counter_ureg()
type = 3;
}
- m_lcntr = GET_UREG(ureg);
- if (m_lcntr > 0)
+ m_core->lcntr = GET_UREG(ureg);
+ if (m_core->lcntr > 0)
{
- PUSH_PC(m_pc+1);
- PUSH_LOOP(address, cond, type, m_lcntr);
+ PUSH_PC(m_core->pc+1);
+ PUSH_LOOP(address, cond, type, m_core->lcntr);
}
}
@@ -2451,11 +2413,11 @@ void adsp21062_device::sharcop_do_until_counter_ureg()
/* do until */
void adsp21062_device::sharcop_do_until()
{
- int cond = (m_opcode >> 33) & 0x1f;
- int offset = SIGN_EXTEND24(m_opcode & 0xffffff);
- UINT32 address = (m_pc + offset);
+ int cond = (m_core->opcode >> 33) & 0x1f;
+ int offset = SIGN_EXTEND24(m_core->opcode & 0xffffff);
+ UINT32 address = (m_core->pc + offset);
- PUSH_PC(m_pc+1);
+ PUSH_PC(m_core->pc+1);
PUSH_LOOP(address, cond, 0, 0);
}
@@ -2465,8 +2427,8 @@ void adsp21062_device::sharcop_do_until()
/* ureg <- DM (direct addressing) */
void adsp21062_device::sharcop_dm_to_ureg_direct()
{
- int ureg = (m_opcode >> 32) & 0xff;
- UINT32 address = (UINT32)(m_opcode);
+ int ureg = (m_core->opcode >> 32) & 0xff;
+ UINT32 address = (UINT32)(m_core->opcode);
SET_UREG(ureg, dm_read32(address));
}
@@ -2474,8 +2436,8 @@ void adsp21062_device::sharcop_dm_to_ureg_direct()
/* ureg -> DM (direct addressing) */
void adsp21062_device::sharcop_ureg_to_dm_direct()
{
- int ureg = (m_opcode >> 32) & 0xff;
- UINT32 address = (UINT32)(m_opcode);
+ int ureg = (m_core->opcode >> 32) & 0xff;
+ UINT32 address = (UINT32)(m_core->opcode);
dm_write32(address, GET_UREG(ureg));
}
@@ -2483,12 +2445,12 @@ void adsp21062_device::sharcop_ureg_to_dm_direct()
/* ureg <- PM (direct addressing) */
void adsp21062_device::sharcop_pm_to_ureg_direct()
{
- int ureg = (m_opcode >> 32) & 0xff;
- UINT32 address = (UINT32)(m_opcode);
+ int ureg = (m_core->opcode >> 32) & 0xff;
+ UINT32 address = (UINT32)(m_core->opcode);
if (ureg == 0xdb) // PX is 48-bit
{
- m_px = pm_read48(address);
+ m_core->px = pm_read48(address);
}
else
{
@@ -2499,12 +2461,12 @@ void adsp21062_device::sharcop_pm_to_ureg_direct()
/* ureg -> PM (direct addressing) */
void adsp21062_device::sharcop_ureg_to_pm_direct()
{
- int ureg = (m_opcode >> 32) & 0xff;
- UINT32 address = (UINT32)(m_opcode);
+ int ureg = (m_core->opcode >> 32) & 0xff;
+ UINT32 address = (UINT32)(m_core->opcode);
if (ureg == 0xdb) // PX is 48-bit
{
- pm_write48(address, m_px);
+ pm_write48(address, m_core->px);
}
else
{
@@ -2518,9 +2480,9 @@ void adsp21062_device::sharcop_ureg_to_pm_direct()
/* ureg <- DM (indirect addressing) */
void adsp21062_device::sharcop_dm_to_ureg_indirect()
{
- int ureg = (m_opcode >> 32) & 0xff;
- UINT32 offset = (UINT32)m_opcode;
- int i = (m_opcode >> 41) & 0x7;
+ int ureg = (m_core->opcode >> 32) & 0xff;
+ UINT32 offset = (UINT32)m_core->opcode;
+ int i = (m_core->opcode >> 41) & 0x7;
SET_UREG(ureg, dm_read32(DM_REG_I(i) + offset));
}
@@ -2528,9 +2490,9 @@ void adsp21062_device::sharcop_dm_to_ureg_indirect()
/* ureg -> DM (indirect addressing) */
void adsp21062_device::sharcop_ureg_to_dm_indirect()
{
- int ureg = (m_opcode >> 32) & 0xff;
- UINT32 offset = (UINT32)m_opcode;
- int i = (m_opcode >> 41) & 0x7;
+ int ureg = (m_core->opcode >> 32) & 0xff;
+ UINT32 offset = (UINT32)m_core->opcode;
+ int i = (m_core->opcode >> 41) & 0x7;
dm_write32(DM_REG_I(i) + offset, GET_UREG(ureg));
}
@@ -2538,13 +2500,13 @@ void adsp21062_device::sharcop_ureg_to_dm_indirect()
/* ureg <- PM (indirect addressing) */
void adsp21062_device::sharcop_pm_to_ureg_indirect()
{
- int ureg = (m_opcode >> 32) & 0xff;
- UINT32 offset = m_opcode & 0xffffff;
- int i = (m_opcode >> 41) & 0x7;
+ int ureg = (m_core->opcode >> 32) & 0xff;
+ UINT32 offset = m_core->opcode & 0xffffff;
+ int i = (m_core->opcode >> 41) & 0x7;
if (ureg == 0xdb) /* PX is 48-bit */
{
- m_px = pm_read48(PM_REG_I(i) + offset);
+ m_core->px = pm_read48(PM_REG_I(i) + offset);
}
else
{
@@ -2555,13 +2517,13 @@ void adsp21062_device::sharcop_pm_to_ureg_indirect()
/* ureg -> PM (indirect addressing) */
void adsp21062_device::sharcop_ureg_to_pm_indirect()
{
- int ureg = (m_opcode >> 32) & 0xff;
- UINT32 offset = (UINT32)m_opcode;
- int i = (m_opcode >> 41) & 0x7;
+ int ureg = (m_core->opcode >> 32) & 0xff;
+ UINT32 offset = (UINT32)m_core->opcode;
+ int i = (m_core->opcode >> 41) & 0x7;
if (ureg == 0xdb) /* PX is 48-bit */
{
- pm_write48(PM_REG_I(i) + offset, m_px);
+ pm_write48(PM_REG_I(i) + offset, m_core->px);
}
else
{
@@ -2575,10 +2537,10 @@ void adsp21062_device::sharcop_ureg_to_pm_indirect()
/* immediate data -> DM|PM */
void adsp21062_device::sharcop_imm_to_dmpm()
{
- int i = (m_opcode >> 41) & 0x7;
- int m = (m_opcode >> 38) & 0x7;
- int g = (m_opcode >> 37) & 0x1;
- UINT32 data = (UINT32)m_opcode;
+ int i = (m_core->opcode >> 41) & 0x7;
+ int m = (m_core->opcode >> 38) & 0x7;
+ int g = (m_core->opcode >> 37) & 0x1;
+ UINT32 data = (UINT32)m_core->opcode;
if (g)
{
@@ -2602,8 +2564,8 @@ void adsp21062_device::sharcop_imm_to_dmpm()
/* immediate data -> ureg */
void adsp21062_device::sharcop_imm_to_ureg()
{
- int ureg = (m_opcode >> 32) & 0xff;
- UINT32 data = (UINT32)m_opcode;
+ int ureg = (m_core->opcode >> 32) & 0xff;
+ UINT32 data = (UINT32)m_core->opcode;
SET_UREG(ureg, data);
}
@@ -2614,9 +2576,9 @@ void adsp21062_device::sharcop_imm_to_ureg()
/* system register bit manipulation */
void adsp21062_device::sharcop_sysreg_bitop()
{
- int bop = (m_opcode >> 37) & 0x7;
- int sreg = (m_opcode >> 32) & 0xf;
- UINT32 data = (UINT32)m_opcode;
+ int bop = (m_core->opcode >> 37) & 0x7;
+ int sreg = (m_core->opcode >> 32) & 0xf;
+ UINT32 data = (UINT32)m_core->opcode;
UINT32 src = GET_UREG(0x70 | sreg);
@@ -2641,11 +2603,11 @@ void adsp21062_device::sharcop_sysreg_bitop()
{
if ((src & data) == data)
{
- m_astat |= BTF;
+ m_core->astat |= BTF;
}
else
{
- m_astat &= ~BTF;
+ m_core->astat &= ~BTF;
}
break;
}
@@ -2653,11 +2615,11 @@ void adsp21062_device::sharcop_sysreg_bitop()
{
if (src == data)
{
- m_astat |= BTF;
+ m_core->astat |= BTF;
}
else
{
- m_astat &= ~BTF;
+ m_core->astat &= ~BTF;
}
break;
}
@@ -2675,9 +2637,9 @@ void adsp21062_device::sharcop_sysreg_bitop()
/* I register modify */
void adsp21062_device::sharcop_modify()
{
- int g = (m_opcode >> 38) & 0x1;
- int i = (m_opcode >> 32) & 0x7;
- INT32 data = (m_opcode);
+ int g = (m_core->opcode >> 38) & 0x1;
+ int i = (m_core->opcode >> 32) & 0x7;
+ INT32 data = (m_core->opcode);
if (g) // PM
{
@@ -2706,29 +2668,29 @@ void adsp21062_device::sharcop_bit_reverse()
/* push/pop stacks / flush cache */
void adsp21062_device::sharcop_push_pop_stacks()
{
- if (m_opcode & U64(0x008000000000))
+ if (m_core->opcode & U64(0x008000000000))
{
fatalerror("sharcop_push_pop_stacks: push loop not implemented\n");
}
- if (m_opcode & U64(0x004000000000))
+ if (m_core->opcode & U64(0x004000000000))
{
fatalerror("sharcop_push_pop_stacks: pop loop not implemented\n");
}
- if (m_opcode & U64(0x002000000000))
+ if (m_core->opcode & U64(0x002000000000))
{
//fatalerror("sharcop_push_pop_stacks: push sts not implemented\n");
PUSH_STATUS_STACK();
}
- if (m_opcode & U64(0x001000000000))
+ if (m_core->opcode & U64(0x001000000000))
{
//fatalerror("sharcop_push_pop_stacks: pop sts not implemented\n");
POP_STATUS_STACK();
}
- if (m_opcode & U64(0x000800000000))
+ if (m_core->opcode & U64(0x000800000000))
{
- PUSH_PC(m_pcstk);
+ PUSH_PC(m_core->pcstk);
}
- if (m_opcode & U64(0x000400000000))
+ if (m_core->opcode & U64(0x000400000000))
{
POP_PC();
}
@@ -2746,13 +2708,13 @@ void adsp21062_device::sharcop_nop()
void adsp21062_device::sharcop_idle()
{
- //CHANGE_PC(m_pc);
+ //CHANGE_PC(m_core->pc);
- m_daddr = m_pc;
- m_faddr = m_pc+1;
- m_nfaddr = m_pc+2;
+ m_core->daddr = m_core->pc;
+ m_core->faddr = m_core->pc+1;
+ m_core->nfaddr = m_core->pc+2;
- m_idle = 1;
+ m_core->idle = 1;
}
/*****************************************************************************/
@@ -2761,7 +2723,7 @@ void adsp21062_device::sharcop_unimplemented()
{
extern CPU_DISASSEMBLE(sharc);
char dasm[1000];
- CPU_DISASSEMBLE_NAME(sharc)(nullptr, dasm, m_pc, nullptr, nullptr, 0);
- osd_printf_debug("SHARC: %08X: %s\n", m_pc, dasm);
- fatalerror("SHARC: Unimplemented opcode %04X%08X at %08X\n", (UINT16)(m_opcode >> 32), (UINT32)(m_opcode), m_pc);
+ CPU_DISASSEMBLE_NAME(sharc)(nullptr, dasm, m_core->pc, nullptr, nullptr, 0);
+ osd_printf_debug("SHARC: %08X: %s\n", m_core->pc, dasm);
+ fatalerror("SHARC: Unimplemented opcode %04X%08X at %08X\n", (UINT16)(m_core->opcode >> 32), (UINT32)(m_core->opcode), m_core->pc);
}