mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-23 04:33:24 +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
|
||||
#endif
|
||||
|
||||
#if defined(PPC_EXECUTE_DUMP_STATE) && !defined(PPC_NO_DECODE_CACHE)
|
||||
#define PPC_NO_DECODE_CACHE
|
||||
#endif
|
||||
|
||||
#ifdef PPC_NO_DECODE_CACHE
|
||||
#undef PPC_LAZY_PC_UPDATE
|
||||
#endif
|
||||
|
||||
#if PPC_FLIGHT_RECORDER
|
||||
#if PPC_FLIGHT_RECORDER || PPC_EXECUTE_DUMP_STATE
|
||||
#undef PPC_LAZY_PC_UPDATE
|
||||
#endif
|
||||
|
||||
|
@ -113,7 +113,6 @@ void powerpc_cpu::init_flight_recorder()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PPC_FLIGHT_RECORDER
|
||||
void powerpc_cpu::record_step(uint32 opcode)
|
||||
{
|
||||
#if PPC_FLIGHT_RECORDER
|
||||
@ -141,6 +140,7 @@ void powerpc_cpu::record_step(uint32 opcode)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PPC_FLIGHT_RECORDER
|
||||
void powerpc_cpu::start_log()
|
||||
{
|
||||
logging = true;
|
||||
@ -264,6 +264,16 @@ void powerpc_cpu::dump_registers()
|
||||
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 {
|
||||
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()
|
||||
decode_cache_end_p -= 2;
|
||||
#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();
|
||||
#endif
|
||||
|
@ -203,12 +203,12 @@ public:
|
||||
|
||||
// Handle flight recorder
|
||||
#if PPC_FLIGHT_RECORDER
|
||||
bool is_logging() { return logging; }
|
||||
bool is_logging() const { return logging; }
|
||||
void start_log();
|
||||
void stop_log();
|
||||
void dump_log(const char *filename = NULL);
|
||||
#else
|
||||
bool is_logging() { return false; }
|
||||
bool is_logging() const { return false; }
|
||||
void start_log() { }
|
||||
void stop_log() { }
|
||||
void dump_log(const char *filename = NULL) { }
|
||||
@ -216,6 +216,8 @@ public:
|
||||
|
||||
// Dump registers
|
||||
void dump_registers();
|
||||
void dump_instruction(uint32 opcode);
|
||||
void fake_dump_registers(uint32);
|
||||
|
||||
// Start emulation loop
|
||||
template< class prologue, class epilogue >
|
||||
@ -260,7 +262,7 @@ private:
|
||||
typedef powerpc_block_info block_info;
|
||||
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);
|
||||
block_info::decode_info * decode_cache;
|
||||
block_info::decode_info * decode_cache_p;
|
||||
@ -338,13 +340,17 @@ private:
|
||||
template< class prologue, class epilogue >
|
||||
inline void powerpc_cpu::do_execute()
|
||||
{
|
||||
#ifdef PPC_EXECUTE_DUMP_STATE
|
||||
const bool dump_state = true;
|
||||
#endif
|
||||
#ifdef PPC_NO_DECODE_CACHE
|
||||
for (;;) {
|
||||
prologue::execute(this);
|
||||
uint32 opcode = vm_read_memory_4(pc());
|
||||
const instr_info_t *ii = decode(opcode);
|
||||
#ifdef PPC_EXECUTE_DUMP_STATE
|
||||
fprintf(stderr, "[%08x]-> %08x\n", pc(), opcode);
|
||||
if (dump_state)
|
||||
dump_instruction(opcode);
|
||||
#endif
|
||||
#if PPC_FLIGHT_RECORDER
|
||||
if (is_logging())
|
||||
@ -353,6 +359,7 @@ inline void powerpc_cpu::do_execute()
|
||||
assert(ii->execute != 0);
|
||||
(this->*(ii->execute))(opcode);
|
||||
#ifdef PPC_EXECUTE_DUMP_STATE
|
||||
if (dump_state)
|
||||
dump_registers();
|
||||
#endif
|
||||
epilogue::execute(this);
|
||||
@ -369,6 +376,12 @@ inline void powerpc_cpu::do_execute()
|
||||
do {
|
||||
uint32 opcode = vm_read_memory_4(dpc += 4);
|
||||
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 (is_logging()) {
|
||||
di->opcode = opcode;
|
||||
@ -378,7 +391,15 @@ inline void powerpc_cpu::do_execute()
|
||||
#endif
|
||||
di->opcode = opcode;
|
||||
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();
|
||||
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
|
||||
},
|
||||
{ "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,
|
||||
XO_form, 31, 234, CFLOW_NORMAL
|
||||
},
|
||||
{ "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,
|
||||
XO_form, 31, 202, CFLOW_NORMAL
|
||||
},
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "sysdeps.h"
|
||||
#include "cpu/ppc/ppc-cpu.hpp"
|
||||
|
||||
#define TEST_RA_IS_0 0
|
||||
#define TEST_ADD 0
|
||||
#define TEST_SUB 0
|
||||
#define TEST_MUL 0
|
||||
@ -31,7 +32,7 @@
|
||||
#define TEST_MISC 0
|
||||
#define TEST_LOGICAL 0
|
||||
#define TEST_COMPARE 0
|
||||
#define TEST_CR_LOGICAL 1
|
||||
#define TEST_CR_LOGICAL 0
|
||||
|
||||
// Partial PowerPC runtime assembler from GNU lightning
|
||||
#define _I(X) ((uint32)(X))
|
||||
@ -108,7 +109,11 @@ private:
|
||||
enum {
|
||||
R_ = -1,
|
||||
RD = 10,
|
||||
#if TEST_RA_IS_0
|
||||
RA = 0,
|
||||
#else
|
||||
RA = 11,
|
||||
#endif
|
||||
RB = 12
|
||||
};
|
||||
|
||||
@ -121,6 +126,7 @@ private:
|
||||
void test_logical(void);
|
||||
void test_compare(void);
|
||||
void test_cr_logical(void);
|
||||
void test_load_multiple(void);
|
||||
};
|
||||
|
||||
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" : "__"));
|
||||
}
|
||||
|
||||
#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_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_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_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(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)
|
||||
{
|
||||
#if TEST_GENERIC_ARITH
|
||||
#if TEST_LOGICAL
|
||||
TEST_INSTRUCTION(RRR__,"and.", _X (31,RA,RD,RB,28,1));
|
||||
TEST_INSTRUCTION(RRR__,"andc.", _X (31,RA,RD,RB,60,1));
|
||||
TEST_INSTRUCTION(RRK__,"andi.", _D (28,RA,RD,00));
|
||||
@ -694,6 +707,18 @@ void powerpc_test_cpu::test_cr_logical(void)
|
||||
#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)
|
||||
{
|
||||
// Tests initialization
|
||||
@ -711,6 +736,7 @@ bool powerpc_test_cpu::test(void)
|
||||
test_logical();
|
||||
test_compare();
|
||||
test_cr_logical();
|
||||
test_load_multiple();
|
||||
|
||||
printf("%u errors out of %u tests\n", errors, tests);
|
||||
return errors != 0;
|
||||
|
Loading…
Reference in New Issue
Block a user