mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-27 02:49:42 +00:00
- Fix ADDME & ADDZE decoders, add RA==R0 testers
- Increase predecode cache size to 32K entries - Enable PPC_EXECUTE_DUMP_STATE for predecode cache as well
This commit is contained in:
parent
309c2f0bd5
commit
9a05805a27
@ -177,15 +177,11 @@
|
|||||||
#undef PPC_NO_STATIC_II_INDEX_TABLE
|
#undef PPC_NO_STATIC_II_INDEX_TABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PPC_EXECUTE_DUMP_STATE) && !defined(PPC_NO_DECODE_CACHE)
|
|
||||||
#define PPC_NO_DECODE_CACHE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PPC_NO_DECODE_CACHE
|
#ifdef PPC_NO_DECODE_CACHE
|
||||||
#undef PPC_LAZY_PC_UPDATE
|
#undef PPC_LAZY_PC_UPDATE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PPC_FLIGHT_RECORDER
|
#if PPC_FLIGHT_RECORDER || PPC_EXECUTE_DUMP_STATE
|
||||||
#undef PPC_LAZY_PC_UPDATE
|
#undef PPC_LAZY_PC_UPDATE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -113,7 +113,6 @@ void powerpc_cpu::init_flight_recorder()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PPC_FLIGHT_RECORDER
|
|
||||||
void powerpc_cpu::record_step(uint32 opcode)
|
void powerpc_cpu::record_step(uint32 opcode)
|
||||||
{
|
{
|
||||||
#if PPC_FLIGHT_RECORDER
|
#if PPC_FLIGHT_RECORDER
|
||||||
@ -141,6 +140,7 @@ void powerpc_cpu::record_step(uint32 opcode)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PPC_FLIGHT_RECORDER
|
||||||
void powerpc_cpu::start_log()
|
void powerpc_cpu::start_log()
|
||||||
{
|
{
|
||||||
logging = true;
|
logging = true;
|
||||||
@ -264,6 +264,16 @@ void powerpc_cpu::dump_registers()
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void powerpc_cpu::dump_instruction(uint32 opcode)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "[%08x]-> %08x\n", pc(), opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void powerpc_cpu::fake_dump_registers(uint32)
|
||||||
|
{
|
||||||
|
dump_registers();
|
||||||
|
}
|
||||||
|
|
||||||
struct execute_nothing {
|
struct execute_nothing {
|
||||||
static inline void execute(powerpc_cpu *) { }
|
static inline void execute(powerpc_cpu *) { }
|
||||||
};
|
};
|
||||||
@ -289,6 +299,10 @@ void powerpc_cpu::init_decode_cache()
|
|||||||
// Leave enough room to last call to record_step()
|
// Leave enough room to last call to record_step()
|
||||||
decode_cache_end_p -= 2;
|
decode_cache_end_p -= 2;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef PPC_EXECUTE_DUMP_STATE
|
||||||
|
// Leave enough room to last calls to dump state functions
|
||||||
|
decode_cache_end_p -= 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
block_cache.initialize();
|
block_cache.initialize();
|
||||||
#endif
|
#endif
|
||||||
|
@ -203,12 +203,12 @@ public:
|
|||||||
|
|
||||||
// Handle flight recorder
|
// Handle flight recorder
|
||||||
#if PPC_FLIGHT_RECORDER
|
#if PPC_FLIGHT_RECORDER
|
||||||
bool is_logging() { return logging; }
|
bool is_logging() const { return logging; }
|
||||||
void start_log();
|
void start_log();
|
||||||
void stop_log();
|
void stop_log();
|
||||||
void dump_log(const char *filename = NULL);
|
void dump_log(const char *filename = NULL);
|
||||||
#else
|
#else
|
||||||
bool is_logging() { return false; }
|
bool is_logging() const { return false; }
|
||||||
void start_log() { }
|
void start_log() { }
|
||||||
void stop_log() { }
|
void stop_log() { }
|
||||||
void dump_log(const char *filename = NULL) { }
|
void dump_log(const char *filename = NULL) { }
|
||||||
@ -216,6 +216,8 @@ public:
|
|||||||
|
|
||||||
// Dump registers
|
// Dump registers
|
||||||
void dump_registers();
|
void dump_registers();
|
||||||
|
void dump_instruction(uint32 opcode);
|
||||||
|
void fake_dump_registers(uint32);
|
||||||
|
|
||||||
// Start emulation loop
|
// Start emulation loop
|
||||||
template< class prologue, class epilogue >
|
template< class prologue, class epilogue >
|
||||||
@ -260,7 +262,7 @@ private:
|
|||||||
typedef powerpc_block_info block_info;
|
typedef powerpc_block_info block_info;
|
||||||
block_cache< block_info, lazy_allocator > block_cache;
|
block_cache< block_info, lazy_allocator > block_cache;
|
||||||
|
|
||||||
static const uint32 DECODE_CACHE_MAX_ENTRIES = 20000;
|
static const uint32 DECODE_CACHE_MAX_ENTRIES = 32768;
|
||||||
static const uint32 DECODE_CACHE_SIZE = DECODE_CACHE_MAX_ENTRIES * sizeof(block_info::decode_info);
|
static const uint32 DECODE_CACHE_SIZE = DECODE_CACHE_MAX_ENTRIES * sizeof(block_info::decode_info);
|
||||||
block_info::decode_info * decode_cache;
|
block_info::decode_info * decode_cache;
|
||||||
block_info::decode_info * decode_cache_p;
|
block_info::decode_info * decode_cache_p;
|
||||||
@ -338,13 +340,17 @@ private:
|
|||||||
template< class prologue, class epilogue >
|
template< class prologue, class epilogue >
|
||||||
inline void powerpc_cpu::do_execute()
|
inline void powerpc_cpu::do_execute()
|
||||||
{
|
{
|
||||||
|
#ifdef PPC_EXECUTE_DUMP_STATE
|
||||||
|
const bool dump_state = true;
|
||||||
|
#endif
|
||||||
#ifdef PPC_NO_DECODE_CACHE
|
#ifdef PPC_NO_DECODE_CACHE
|
||||||
for (;;) {
|
for (;;) {
|
||||||
prologue::execute(this);
|
prologue::execute(this);
|
||||||
uint32 opcode = vm_read_memory_4(pc());
|
uint32 opcode = vm_read_memory_4(pc());
|
||||||
const instr_info_t *ii = decode(opcode);
|
const instr_info_t *ii = decode(opcode);
|
||||||
#ifdef PPC_EXECUTE_DUMP_STATE
|
#ifdef PPC_EXECUTE_DUMP_STATE
|
||||||
fprintf(stderr, "[%08x]-> %08x\n", pc(), opcode);
|
if (dump_state)
|
||||||
|
dump_instruction(opcode);
|
||||||
#endif
|
#endif
|
||||||
#if PPC_FLIGHT_RECORDER
|
#if PPC_FLIGHT_RECORDER
|
||||||
if (is_logging())
|
if (is_logging())
|
||||||
@ -353,6 +359,7 @@ inline void powerpc_cpu::do_execute()
|
|||||||
assert(ii->execute != 0);
|
assert(ii->execute != 0);
|
||||||
(this->*(ii->execute))(opcode);
|
(this->*(ii->execute))(opcode);
|
||||||
#ifdef PPC_EXECUTE_DUMP_STATE
|
#ifdef PPC_EXECUTE_DUMP_STATE
|
||||||
|
if (dump_state)
|
||||||
dump_registers();
|
dump_registers();
|
||||||
#endif
|
#endif
|
||||||
epilogue::execute(this);
|
epilogue::execute(this);
|
||||||
@ -369,6 +376,12 @@ inline void powerpc_cpu::do_execute()
|
|||||||
do {
|
do {
|
||||||
uint32 opcode = vm_read_memory_4(dpc += 4);
|
uint32 opcode = vm_read_memory_4(dpc += 4);
|
||||||
ii = decode(opcode);
|
ii = decode(opcode);
|
||||||
|
#ifdef PPC_EXECUTE_DUMP_STATE
|
||||||
|
if (dump_state) {
|
||||||
|
di->opcode = opcode;
|
||||||
|
di->execute = &powerpc_cpu::dump_instruction;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if PPC_FLIGHT_RECORDER
|
#if PPC_FLIGHT_RECORDER
|
||||||
if (is_logging()) {
|
if (is_logging()) {
|
||||||
di->opcode = opcode;
|
di->opcode = opcode;
|
||||||
@ -378,7 +391,15 @@ inline void powerpc_cpu::do_execute()
|
|||||||
#endif
|
#endif
|
||||||
di->opcode = opcode;
|
di->opcode = opcode;
|
||||||
di->execute = ii->execute;
|
di->execute = ii->execute;
|
||||||
if (++di >= decode_cache_end_p) {
|
di++;
|
||||||
|
#ifdef PPC_EXECUTE_DUMP_STATE
|
||||||
|
if (dump_state) {
|
||||||
|
di->opcode = 0;
|
||||||
|
di->execute = &powerpc_cpu::fake_dump_registers;
|
||||||
|
di++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (di >= decode_cache_end_p) {
|
||||||
// Invalidate cache and move current code to start
|
// Invalidate cache and move current code to start
|
||||||
invalidate_cache();
|
invalidate_cache();
|
||||||
const int blocklen = di - bi->di;
|
const int blocklen = di - bi->di;
|
||||||
|
@ -122,12 +122,12 @@ const powerpc_cpu::instr_info_t powerpc_cpu::powerpc_ii_table[] = {
|
|||||||
D_form, 15, 0, CFLOW_NORMAL
|
D_form, 15, 0, CFLOW_NORMAL
|
||||||
},
|
},
|
||||||
{ "addme",
|
{ "addme",
|
||||||
EXECUTE_ADDITION(RA_or_0, MINUS_ONE, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G),
|
EXECUTE_ADDITION(RA, MINUS_ONE, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G),
|
||||||
NULL,
|
NULL,
|
||||||
XO_form, 31, 234, CFLOW_NORMAL
|
XO_form, 31, 234, CFLOW_NORMAL
|
||||||
},
|
},
|
||||||
{ "addze",
|
{ "addze",
|
||||||
EXECUTE_ADDITION(RA_or_0, ZERO, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G),
|
EXECUTE_ADDITION(RA, ZERO, XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G),
|
||||||
NULL,
|
NULL,
|
||||||
XO_form, 31, 202, CFLOW_NORMAL
|
XO_form, 31, 202, CFLOW_NORMAL
|
||||||
},
|
},
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "sysdeps.h"
|
#include "sysdeps.h"
|
||||||
#include "cpu/ppc/ppc-cpu.hpp"
|
#include "cpu/ppc/ppc-cpu.hpp"
|
||||||
|
|
||||||
|
#define TEST_RA_IS_0 0
|
||||||
#define TEST_ADD 0
|
#define TEST_ADD 0
|
||||||
#define TEST_SUB 0
|
#define TEST_SUB 0
|
||||||
#define TEST_MUL 0
|
#define TEST_MUL 0
|
||||||
@ -31,7 +32,7 @@
|
|||||||
#define TEST_MISC 0
|
#define TEST_MISC 0
|
||||||
#define TEST_LOGICAL 0
|
#define TEST_LOGICAL 0
|
||||||
#define TEST_COMPARE 0
|
#define TEST_COMPARE 0
|
||||||
#define TEST_CR_LOGICAL 1
|
#define TEST_CR_LOGICAL 0
|
||||||
|
|
||||||
// Partial PowerPC runtime assembler from GNU lightning
|
// Partial PowerPC runtime assembler from GNU lightning
|
||||||
#define _I(X) ((uint32)(X))
|
#define _I(X) ((uint32)(X))
|
||||||
@ -108,7 +109,11 @@ private:
|
|||||||
enum {
|
enum {
|
||||||
R_ = -1,
|
R_ = -1,
|
||||||
RD = 10,
|
RD = 10,
|
||||||
|
#if TEST_RA_IS_0
|
||||||
|
RA = 0,
|
||||||
|
#else
|
||||||
RA = 11,
|
RA = 11,
|
||||||
|
#endif
|
||||||
RB = 12
|
RB = 12
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -121,6 +126,7 @@ private:
|
|||||||
void test_logical(void);
|
void test_logical(void);
|
||||||
void test_compare(void);
|
void test_compare(void);
|
||||||
void test_cr_logical(void);
|
void test_cr_logical(void);
|
||||||
|
void test_load_multiple(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
void powerpc_test_cpu::execute_return(uint32 opcode)
|
void powerpc_test_cpu::execute_return(uint32 opcode)
|
||||||
@ -179,18 +185,25 @@ void powerpc_test_cpu::print_flags(uint32 cr, uint32 xer, int crf) const
|
|||||||
(xer & XER_CA_field::mask() ? "CA" : "__"));
|
(xer & XER_CA_field::mask() ? "CA" : "__"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TEST_RA_IS_0
|
||||||
|
#define ASM_RA_REG asm("r0")
|
||||||
|
#else
|
||||||
|
#define ASM_RA_REG /**/
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TEST_ASM______(OP,D0,A0,A1,A2,A3) asm volatile (OP : : : "cc")
|
#define TEST_ASM______(OP,D0,A0,A1,A2,A3) asm volatile (OP : : : "cc")
|
||||||
#define TEST_ASM_R____(OP,RD,A0,A1,A2,A3) asm volatile (OP " %0" : "=r" (RD) : : "cc")
|
#define TEST_ASM_R____(OP,RD,A0,A1,A2,A3) asm volatile (OP " %0" : "=r" (RD) : : "cc")
|
||||||
#define TEST_ASM_RR___(OP,RD,RA,A1,A2,A3) asm volatile (OP " %0,%1" : "=r" (RD) : "r" (RA) : "cc")
|
#define TEST_ASM_RA_OR_0(RA, ASM_EXPR) do { register uint32 _RA ASM_RA_REG = RA; asm volatile ASM_EXPR; } while (0)
|
||||||
|
#define TEST_ASM_RR___(OP,RD,RA,A1,A2,A3) TEST_ASM_RA_OR_0(RA, (OP " %0,%1" : "=r" (RD) : "r" (_RA) : "cc"))
|
||||||
|
#define TEST_ASM_RRS__(OP,RD,RA,IM,A2,A3) TEST_ASM_RA_OR_0(RA, (OP " %0,%1,%2" : "=r" (RD) : "r" (_RA), "i" (IM) : "cc"))
|
||||||
|
#define TEST_ASM_RRI__(OP,RD,RA,IM,A2,A3) TEST_ASM_RA_OR_0(RA, (OP " %0,%1,%2" : "=r" (RD) : "r" (_RA), "I" (int16(IM)) : "cc"))
|
||||||
|
#define TEST_ASM_RRK__(OP,RD,RA,IM,A2,A3) TEST_ASM_RA_OR_0(RA, (OP " %0,%1,%2" : "=r" (RD) : "r" (_RA), "K" (IM) : "cc"))
|
||||||
|
#define TEST_ASM_RRR__(OP,RD,RA,RB,A2,A3) TEST_ASM_RA_OR_0(RA, (OP " %0,%1,%2" : "=r" (RD) : "r" (_RA), "r" (RB) : "cc"))
|
||||||
|
#define TEST_ASM_RRIII(OP,RD,RA,SH,MB,ME) TEST_ASM_RA_OR_0(RA, (OP " %0,%1,%2,%3,%4" : "+r" (RD) : "r" (_RA), "i" (SH), "i" (MB), "i" (ME)))
|
||||||
|
#define TEST_ASM_RRRII(OP,RD,RA,RB,MB,ME) TEST_ASM_RA_OR_0(RA, (OP " %0,%1,%2,%3,%4" : "+r" (RD) : "r" (_RA), "r" (RB), "i" (MB), "i" (ME)))
|
||||||
#define TEST_ASM_CRR__(OP,RD,CR,RA,RB,A3) asm volatile (OP " %0,%1,%2" : : "i" (CR), "r" (RA), "r" (RB) : "cc")
|
#define TEST_ASM_CRR__(OP,RD,CR,RA,RB,A3) asm volatile (OP " %0,%1,%2" : : "i" (CR), "r" (RA), "r" (RB) : "cc")
|
||||||
#define TEST_ASM_CRI__(OP,RD,CR,RA,IM,A3) asm volatile (OP " %0,%1,%2" : : "i" (CR), "r" (RA), "I" (int16(IM)) : "cc")
|
#define TEST_ASM_CRI__(OP,RD,CR,RA,IM,A3) asm volatile (OP " %0,%1,%2" : : "i" (CR), "r" (RA), "I" (int16(IM)) : "cc")
|
||||||
#define TEST_ASM_CRK__(OP,RD,CR,RA,IM,A3) asm volatile (OP " %0,%1,%2" : : "i" (CR), "r" (RA), "K" (IM) : "cc")
|
#define TEST_ASM_CRK__(OP,RD,CR,RA,IM,A3) asm volatile (OP " %0,%1,%2" : : "i" (CR), "r" (RA), "K" (IM) : "cc")
|
||||||
#define TEST_ASM_RRS__(OP,RD,RA,IM,A2,A3) asm volatile (OP " %0,%1,%2" : "=r" (RD) : "r" (RA), "i" (IM) : "cc")
|
|
||||||
#define TEST_ASM_RRI__(OP,RD,RA,IM,A2,A3) asm volatile (OP " %0,%1,%2" : "=r" (RD) : "r" (RA), "I" (int16(IM)) : "cc")
|
|
||||||
#define TEST_ASM_RRK__(OP,RD,RA,IM,A2,A3) asm volatile (OP " %0,%1,%2" : "=r" (RD) : "r" (RA), "K" (IM) : "cc")
|
|
||||||
#define TEST_ASM_RRR__(OP,RD,RA,RB,A2,A3) asm volatile (OP " %0,%1,%2" : "=r" (RD) : "r" (RA), "r" (RB) : "cc")
|
|
||||||
#define TEST_ASM_RRIII(OP,RD,RA,SH,MB,ME) asm volatile (OP " %0,%1,%2,%3,%4" : "+r" (RD) : "r" (RA), "i" (SH), "i" (MB), "i" (ME))
|
|
||||||
#define TEST_ASM_RRRII(OP,RD,RA,RB,MB,ME) asm volatile (OP " %0,%1,%2,%3,%4" : "+r" (RD) : "r" (RA), "r" (RB), "i" (MB), "i" (ME))
|
|
||||||
#define TEST_ASM_CCC__(OP,RD,RA,RB,RC,A3) asm volatile (OP " %0,%1,%2" : : "i" (RA), "i" (RB), "i" (RC) : "cc")
|
#define TEST_ASM_CCC__(OP,RD,RA,RB,RC,A3) asm volatile (OP " %0,%1,%2" : : "i" (RA), "i" (RB), "i" (RC) : "cc")
|
||||||
|
|
||||||
#define TEST_ASM(FORMAT, OP, RD, CR, XER, A0, A1, A2, A3) do { \
|
#define TEST_ASM(FORMAT, OP, RD, CR, XER, A0, A1, A2, A3) do { \
|
||||||
@ -624,7 +637,7 @@ void powerpc_test_cpu::test_div(void)
|
|||||||
|
|
||||||
void powerpc_test_cpu::test_logical(void)
|
void powerpc_test_cpu::test_logical(void)
|
||||||
{
|
{
|
||||||
#if TEST_GENERIC_ARITH
|
#if TEST_LOGICAL
|
||||||
TEST_INSTRUCTION(RRR__,"and.", _X (31,RA,RD,RB,28,1));
|
TEST_INSTRUCTION(RRR__,"and.", _X (31,RA,RD,RB,28,1));
|
||||||
TEST_INSTRUCTION(RRR__,"andc.", _X (31,RA,RD,RB,60,1));
|
TEST_INSTRUCTION(RRR__,"andc.", _X (31,RA,RD,RB,60,1));
|
||||||
TEST_INSTRUCTION(RRK__,"andi.", _D (28,RA,RD,00));
|
TEST_INSTRUCTION(RRK__,"andi.", _D (28,RA,RD,00));
|
||||||
@ -694,6 +707,18 @@ void powerpc_test_cpu::test_cr_logical(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void powerpc_test_cpu::test_load_multiple(void)
|
||||||
|
{
|
||||||
|
#if TEST_LOAD_MULTIPLE && 0
|
||||||
|
uint16 tab[] = { 0x1234, 0x5678, 0x9abc, 0xdef0 };
|
||||||
|
uint32 opcode = _X(31,RD,RA,RB,790,0);
|
||||||
|
gpr(RA) = (uintptr)&tab[0];
|
||||||
|
gpr(RB) = 0;
|
||||||
|
execute(opcode);
|
||||||
|
printf("%08x\n", gpr(RD));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool powerpc_test_cpu::test(void)
|
bool powerpc_test_cpu::test(void)
|
||||||
{
|
{
|
||||||
// Tests initialization
|
// Tests initialization
|
||||||
@ -711,6 +736,7 @@ bool powerpc_test_cpu::test(void)
|
|||||||
test_logical();
|
test_logical();
|
||||||
test_compare();
|
test_compare();
|
||||||
test_cr_logical();
|
test_cr_logical();
|
||||||
|
test_load_multiple();
|
||||||
|
|
||||||
printf("%u errors out of %u tests\n", errors, tests);
|
printf("%u errors out of %u tests\n", errors, tests);
|
||||||
return errors != 0;
|
return errors != 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user