2010-04-13 19:31:31 +00:00
|
|
|
// How to use the DSPJitTester:
|
|
|
|
//
|
|
|
|
// == Before running ==
|
|
|
|
// Make sure to call Initialize to set initial stuff required by int and jit:
|
|
|
|
// DSPJitTester::Initialize();
|
|
|
|
//
|
|
|
|
// == Creation of a testcase ==
|
|
|
|
// Create a testcase for a normal operation:
|
|
|
|
// DSPJitTester tester(0x0004); //taken from DSPTables.cpp, opcodes[]
|
|
|
|
//
|
|
|
|
// Create a testcase for an extended operation:
|
|
|
|
// DSPJitTester tester(0x8000, 0x0004); //NX from opcodes, DR from opcodes_ext
|
|
|
|
//
|
|
|
|
// By default, no messages are written.
|
|
|
|
// To log all operations, set verbose to true:
|
|
|
|
// DSPJitTester tester(0x8000, 0x0004, true);
|
|
|
|
//
|
|
|
|
// You can also choose to only print failing tests:
|
|
|
|
// DSPJitTester tester(0x8000, 0x0004, verbosity_setting, true);
|
|
|
|
// verbose = true will give the same output as verbose,
|
|
|
|
// while verbose = false will only (really!) print failing tests.
|
|
|
|
//
|
|
|
|
// == Setting up values ==
|
|
|
|
// You can set the tester up with values for each DSP register:
|
|
|
|
// tester.AddTestData(DSP_REG_ACC0, 1);
|
|
|
|
// tester.AddTestData(DSP_REG_ACC0, 2);
|
|
|
|
// tester.AddTestData(DSP_REG_ACC0, 3);
|
|
|
|
//
|
|
|
|
// You can also choose to have a few predefined values added for a register:
|
|
|
|
// tester.AddTestData(DSP_REG_ACC0); //see the method body for the values added
|
|
|
|
//
|
|
|
|
// == Running the tests ==
|
|
|
|
// After setup, you can either run JIT against the interpreter
|
|
|
|
// using all predefined register values, pass your own set of
|
|
|
|
// registers or run either of the two independently from each other.
|
|
|
|
//
|
|
|
|
// int failed_tests = tester.TestAll(); //run jit against int, using values from AddTestData
|
|
|
|
// int failed_tests = tester.TestAll(true); //override the value for only_failed to show failure
|
|
|
|
//
|
|
|
|
// SDSP dsp = GetCustomSetOfRegisters();
|
|
|
|
// bool success = tester.Test(dsp); //run jit against int, using a custom set of register values
|
|
|
|
//
|
|
|
|
// SDSP result = tester.RunInterpreter(dsp); //run int alone
|
|
|
|
// SDSP result = tester.RunJit(dsp); //run jit alone
|
|
|
|
//
|
|
|
|
// == Examining results ==
|
|
|
|
// When either verbose or only_failed is set to true, the tester will automatically report
|
|
|
|
// failure to stdout, along with input registers and the differences in output registers.
|
|
|
|
//
|
|
|
|
// tester.Report(); //display a small report afterwards
|
|
|
|
//
|
|
|
|
// SDSP int = tester.GetLastInterpreterDSP(); //examine the DSP set left after running int
|
|
|
|
// SDSP jit = tester.GetLastJitDSP(); //same for jit
|
|
|
|
//
|
|
|
|
// int tests_run = tester.GetRunCount();
|
|
|
|
// int tests_failed = tester.GetFailCount();
|
|
|
|
// const char* tested_instruction = tester.GetInstructionName();
|
|
|
|
// printf("%s ran %d tests and failed %d times\n", tested_instruction, tests_run, tests_failed);
|
|
|
|
//
|
|
|
|
// tester.DumpJittedCode(); //prints the code bytes produced by jit (examine with udcli/udis86 or similar)
|
|
|
|
|
2010-04-09 19:28:18 +00:00
|
|
|
#ifndef __DSP_JIT_TESTER_
|
|
|
|
#define __DSP_JIT_TESTER_
|
|
|
|
|
|
|
|
#include "DSPCore.h"
|
|
|
|
#include "DSPInterpreter.h"
|
2010-04-13 19:31:31 +00:00
|
|
|
#include <map>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
typedef std::vector<u16> TestData;
|
|
|
|
typedef std::map<u8, TestData> TestDataList;
|
|
|
|
typedef TestDataList::iterator TestDataIterator;
|
|
|
|
#define DSP_REG_NUM 32
|
2010-04-09 19:28:18 +00:00
|
|
|
|
|
|
|
class DSPJitTester
|
|
|
|
{
|
|
|
|
UDSPInstruction instruction;
|
|
|
|
const DSPOPCTemplate *opcode_template;
|
|
|
|
DSPEmitter jit;
|
|
|
|
SDSP last_int_dsp;
|
|
|
|
SDSP last_jit_dsp;
|
2010-04-13 19:31:31 +00:00
|
|
|
SDSP last_input_dsp;
|
2010-04-09 19:28:18 +00:00
|
|
|
bool be_verbose;
|
2010-04-13 19:31:31 +00:00
|
|
|
bool failed_only;
|
2010-04-09 19:28:18 +00:00
|
|
|
int run_count;
|
|
|
|
int fail_count;
|
|
|
|
char instruction_name[16];
|
2010-04-13 19:31:31 +00:00
|
|
|
TestDataList test_values;
|
2010-04-09 19:28:18 +00:00
|
|
|
|
|
|
|
bool AreEqual(SDSP&, SDSP&);
|
2010-04-13 19:31:31 +00:00
|
|
|
int TestOne(TestDataIterator, SDSP&);
|
|
|
|
void DumpRegs(SDSP&);
|
2010-04-09 19:28:18 +00:00
|
|
|
public:
|
2010-04-13 19:31:31 +00:00
|
|
|
DSPJitTester(u16 opcode, u16 opcode_ext = 0, bool verbose = false, bool only_failed = false);
|
2010-04-09 19:28:18 +00:00
|
|
|
bool Test(SDSP);
|
2010-04-13 19:31:31 +00:00
|
|
|
int TestAll() { return TestAll(failed_only); }
|
|
|
|
int TestAll(bool verbose_fail);
|
|
|
|
void AddTestData(u8 reg);
|
|
|
|
void AddTestData(u8 reg, u16 value);
|
2010-04-09 19:28:18 +00:00
|
|
|
SDSP RunInterpreter(SDSP);
|
|
|
|
SDSP RunJit(SDSP);
|
|
|
|
void ResetInterpreter();
|
|
|
|
void ResetJit();
|
|
|
|
inline SDSP GetLastInterpreterDSP() { return last_int_dsp; }
|
|
|
|
inline SDSP GetLastJitDSP() { return last_jit_dsp; }
|
|
|
|
inline int GetRunCount() { return run_count; }
|
|
|
|
inline int GetFailCount() { return fail_count; }
|
|
|
|
inline const char* GetInstructionName() { return instruction_name; }
|
|
|
|
void Report();
|
2010-04-11 14:06:46 +00:00
|
|
|
void DumpJittedCode();
|
2010-04-09 19:28:18 +00:00
|
|
|
|
|
|
|
static void Initialize();
|
|
|
|
};
|
|
|
|
|
2010-04-09 19:18:50 +00:00
|
|
|
#endif
|