- 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:
gbeauche 2003-10-18 13:43:25 +00:00
parent 309c2f0bd5
commit 9a05805a27
5 changed files with 80 additions and 23 deletions

View File

@ -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

View File

@ -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

View File

@ -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,7 +359,8 @@ 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
dump_registers(); if (dump_state)
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;

View File

@ -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
}, },

View File

@ -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;