mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
Compiles, runs, and hangs in normal wait.
This commit is contained in:
parent
1b833b6789
commit
12444f6305
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -15,6 +15,8 @@
|
||||||
using namespace xe::cpu;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::ppc;
|
using namespace xe::cpu::ppc;
|
||||||
|
|
||||||
|
using namespace AsmJit;
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
|
@ -23,67 +25,67 @@ namespace x64 {
|
||||||
|
|
||||||
// Floating-point arithmetic (A-8)
|
// Floating-point arithmetic (A-8)
|
||||||
|
|
||||||
XEEMITTER(faddx, 0xFC00002A, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(faddx, 0xFC00002A, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(faddsx, 0xEC00002A, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(faddsx, 0xEC00002A, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fdivx, 0xFC000024, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fdivx, 0xFC000024, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fdivsx, 0xEC000024, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fdivsx, 0xEC000024, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fmulx, 0xFC000032, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fmulx, 0xFC000032, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fmulsx, 0xEC000032, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fmulsx, 0xEC000032, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fresx, 0xEC000030, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fresx, 0xEC000030, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(frsqrtex, 0xFC000034, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(frsqrtex, 0xFC000034, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fsubx, 0xFC000028, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fsubx, 0xFC000028, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fsubsx, 0xEC000028, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fsubsx, 0xEC000028, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fselx, 0xFC00002E, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fselx, 0xFC00002E, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fsqrtx, 0xFC00002C, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fsqrtx, 0xFC00002C, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fsqrtsx, 0xEC00002C, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fsqrtsx, 0xEC00002C, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -91,42 +93,42 @@ XEEMITTER(fsqrtsx, 0xEC00002C, A )(X64Emitter& e, jit_function_t f, InstrD
|
||||||
|
|
||||||
// Floating-point multiply-add (A-9)
|
// Floating-point multiply-add (A-9)
|
||||||
|
|
||||||
XEEMITTER(fmaddx, 0xFC00003A, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fmaddx, 0xFC00003A, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fmaddsx, 0xEC00003A, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fmaddsx, 0xEC00003A, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fmsubx, 0xFC000038, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fmsubx, 0xFC000038, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fmsubsx, 0xEC000038, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fmsubsx, 0xEC000038, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fnmaddx, 0xFC00003E, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fnmaddx, 0xFC00003E, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fnmaddsx, 0xEC00003E, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fnmaddsx, 0xEC00003E, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fnmsubx, 0xFC00003C, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fnmsubx, 0xFC00003C, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fnmsubsx, 0xEC00003C, A )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fnmsubsx, 0xEC00003C, A )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -134,32 +136,32 @@ XEEMITTER(fnmsubsx, 0xEC00003C, A )(X64Emitter& e, jit_function_t f, InstrD
|
||||||
|
|
||||||
// Floating-point rounding and conversion (A-10)
|
// Floating-point rounding and conversion (A-10)
|
||||||
|
|
||||||
XEEMITTER(fcfidx, 0xFC00069C, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fcfidx, 0xFC00069C, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fctidx, 0xFC00065C, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fctidx, 0xFC00065C, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fctidzx, 0xFC00065E, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fctidzx, 0xFC00065E, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fctiwx, 0xFC00001C, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fctiwx, 0xFC00001C, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fctiwzx, 0xFC00001E, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fctiwzx, 0xFC00001E, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(frspx, 0xFC000018, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(frspx, 0xFC000018, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -167,12 +169,12 @@ XEEMITTER(frspx, 0xFC000018, X )(X64Emitter& e, jit_function_t f, InstrD
|
||||||
|
|
||||||
// Floating-point compare (A-11)
|
// Floating-point compare (A-11)
|
||||||
|
|
||||||
XEEMITTER(fcmpo, 0xFC000040, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fcmpo, 0xFC000040, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fcmpu, 0xFC000000, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fcmpu, 0xFC000000, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
// if (FRA) is a NaN or (FRB) is a NaN then
|
// if (FRA) is a NaN or (FRB) is a NaN then
|
||||||
// c <- 0b0001
|
// c <- 0b0001
|
||||||
// else if (FRA) < (FRB) then
|
// else if (FRA) < (FRB) then
|
||||||
|
|
@ -193,32 +195,32 @@ XEEMITTER(fcmpu, 0xFC000000, X )(X64Emitter& e, jit_function_t f, InstrD
|
||||||
|
|
||||||
// Floating-point status and control register (A
|
// Floating-point status and control register (A
|
||||||
|
|
||||||
XEEMITTER(mcrfs, 0xFC000080, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(mcrfs, 0xFC000080, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(mffsx, 0xFC00048E, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(mffsx, 0xFC00048E, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(mtfsb0x, 0xFC00008C, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(mtfsb0x, 0xFC00008C, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(mtfsb1x, 0xFC00004C, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(mtfsb1x, 0xFC00004C, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(mtfsfx, 0xFC00058E, XFL)(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(mtfsfx, 0xFC00058E, XFL)(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(mtfsfix, 0xFC00010C, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(mtfsfix, 0xFC00010C, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -226,22 +228,22 @@ XEEMITTER(mtfsfix, 0xFC00010C, X )(X64Emitter& e, jit_function_t f, InstrD
|
||||||
|
|
||||||
// Floating-point move (A-21)
|
// Floating-point move (A-21)
|
||||||
|
|
||||||
XEEMITTER(fabsx, 0xFC000210, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fabsx, 0xFC000210, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fmrx, 0xFC000090, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fmrx, 0xFC000090, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fnabsx, 0xFC000110, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fnabsx, 0xFC000110, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XEEMITTER(fnegx, 0xFC000050, X )(X64Emitter& e, jit_function_t f, InstrData& i) {
|
XEEMITTER(fnegx, 0xFC000050, X )(X64Emitter& e, Compiler& c, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
XEINSTRNOTIMPLEMENTED();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -24,125 +24,125 @@ namespace x64 {
|
||||||
|
|
||||||
class X64Emitter {
|
class X64Emitter {
|
||||||
public:
|
public:
|
||||||
X64Emitter(xe_memory_ref memory, jit_context_t context);
|
X64Emitter(xe_memory_ref memory);
|
||||||
~X64Emitter();
|
~X64Emitter();
|
||||||
|
|
||||||
jit_context_t context();
|
// jit_context_t context();
|
||||||
|
|
||||||
int PrepareFunction(sdb::FunctionSymbol* symbol);
|
// int PrepareFunction(sdb::FunctionSymbol* symbol);
|
||||||
int MakeFunction(sdb::FunctionSymbol* symbol, jit_function_t fn);
|
// int MakeFunction(sdb::FunctionSymbol* symbol, jit_function_t fn);
|
||||||
|
|
||||||
sdb::FunctionSymbol* symbol();
|
// sdb::FunctionSymbol* symbol();
|
||||||
jit_function_t fn();
|
// jit_function_t fn();
|
||||||
sdb::FunctionBlock* fn_block();
|
// sdb::FunctionBlock* fn_block();
|
||||||
|
|
||||||
jit_value_t get_int32(int32_t value);
|
// jit_value_t get_int32(int32_t value);
|
||||||
jit_value_t get_uint32(uint32_t value);
|
// jit_value_t get_uint32(uint32_t value);
|
||||||
jit_value_t get_int64(int64_t value);
|
// jit_value_t get_int64(int64_t value);
|
||||||
jit_value_t get_uint64(uint64_t value);
|
// jit_value_t get_uint64(uint64_t value);
|
||||||
jit_value_t make_signed(jit_value_t value);
|
// jit_value_t make_signed(jit_value_t value);
|
||||||
jit_value_t make_unsigned(jit_value_t value);
|
// jit_value_t make_unsigned(jit_value_t value);
|
||||||
jit_value_t sign_extend(jit_value_t value, jit_type_t target_type);
|
// jit_value_t sign_extend(jit_value_t value, jit_type_t target_type);
|
||||||
jit_value_t zero_extend(jit_value_t value, jit_type_t target_type);
|
// jit_value_t zero_extend(jit_value_t value, jit_type_t target_type);
|
||||||
jit_value_t trunc_to_sbyte(jit_value_t value);
|
// jit_value_t trunc_to_sbyte(jit_value_t value);
|
||||||
jit_value_t trunc_to_ubyte(jit_value_t value);
|
// jit_value_t trunc_to_ubyte(jit_value_t value);
|
||||||
jit_value_t trunc_to_short(jit_value_t value);
|
// jit_value_t trunc_to_short(jit_value_t value);
|
||||||
jit_value_t trunc_to_int(jit_value_t value);
|
// jit_value_t trunc_to_int(jit_value_t value);
|
||||||
|
|
||||||
int branch_to_block(uint32_t address);
|
// int branch_to_block(uint32_t address);
|
||||||
int branch_to_block_if(uint32_t address, jit_value_t value);
|
// int branch_to_block_if(uint32_t address, jit_value_t value);
|
||||||
int branch_to_block_if_not(uint32_t address, jit_value_t value);
|
// int branch_to_block_if_not(uint32_t address, jit_value_t value);
|
||||||
int branch_to_return();
|
// int branch_to_return();
|
||||||
int branch_to_return_if(jit_value_t value);
|
// int branch_to_return_if(jit_value_t value);
|
||||||
int branch_to_return_if_not(jit_value_t value);
|
// int branch_to_return_if_not(jit_value_t value);
|
||||||
int call_function(sdb::FunctionSymbol* target_symbol, jit_value_t lr,
|
// int call_function(sdb::FunctionSymbol* target_symbol, jit_value_t lr,
|
||||||
bool tail);
|
// bool tail);
|
||||||
|
|
||||||
void TraceBranch(uint32_t cia);
|
// void TraceBranch(uint32_t cia);
|
||||||
int GenerateIndirectionBranch(uint32_t cia, jit_value_t target,
|
// int GenerateIndirectionBranch(uint32_t cia, jit_value_t target,
|
||||||
bool lk, bool likely_local);
|
// bool lk, bool likely_local);
|
||||||
|
|
||||||
jit_value_t LoadStateValue(size_t offset, jit_type_t type,
|
// jit_value_t LoadStateValue(size_t offset, jit_type_t type,
|
||||||
const char* name = "");
|
// const char* name = "");
|
||||||
void StoreStateValue(size_t offset, jit_type_t type, jit_value_t value);
|
// void StoreStateValue(size_t offset, jit_type_t type, jit_value_t value);
|
||||||
|
|
||||||
jit_value_t SetupLocal(jit_type_t type, const char* name);
|
// jit_value_t SetupLocal(jit_type_t type, const char* name);
|
||||||
void FillRegisters();
|
// void FillRegisters();
|
||||||
void SpillRegisters();
|
// void SpillRegisters();
|
||||||
|
|
||||||
jit_value_t xer_value();
|
// jit_value_t xer_value();
|
||||||
void update_xer_value(jit_value_t value);
|
// void update_xer_value(jit_value_t value);
|
||||||
void update_xer_with_overflow(jit_value_t value);
|
// void update_xer_with_overflow(jit_value_t value);
|
||||||
void update_xer_with_carry(jit_value_t value);
|
// void update_xer_with_carry(jit_value_t value);
|
||||||
void update_xer_with_overflow_and_carry(jit_value_t value);
|
// void update_xer_with_overflow_and_carry(jit_value_t value);
|
||||||
|
|
||||||
jit_value_t lr_value();
|
// jit_value_t lr_value();
|
||||||
void update_lr_value(jit_value_t value);
|
// void update_lr_value(jit_value_t value);
|
||||||
|
|
||||||
jit_value_t ctr_value();
|
// jit_value_t ctr_value();
|
||||||
void update_ctr_value(jit_value_t value);
|
// void update_ctr_value(jit_value_t value);
|
||||||
|
|
||||||
jit_value_t cr_value(uint32_t n);
|
// jit_value_t cr_value(uint32_t n);
|
||||||
void update_cr_value(uint32_t n, jit_value_t value);
|
// void update_cr_value(uint32_t n, jit_value_t value);
|
||||||
void update_cr_with_cond(uint32_t n, jit_value_t lhs, jit_value_t rhs,
|
// void update_cr_with_cond(uint32_t n, jit_value_t lhs, jit_value_t rhs,
|
||||||
bool is_signed);
|
// bool is_signed);
|
||||||
|
|
||||||
jit_value_t gpr_value(uint32_t n);
|
// jit_value_t gpr_value(uint32_t n);
|
||||||
void update_gpr_value(uint32_t n, jit_value_t value);
|
// void update_gpr_value(uint32_t n, jit_value_t value);
|
||||||
jit_value_t fpr_value(uint32_t n);
|
// jit_value_t fpr_value(uint32_t n);
|
||||||
void update_fpr_value(uint32_t n, jit_value_t value);
|
// void update_fpr_value(uint32_t n, jit_value_t value);
|
||||||
|
|
||||||
jit_value_t TouchMemoryAddress(uint32_t cia, jit_value_t addr);
|
// jit_value_t TouchMemoryAddress(uint32_t cia, jit_value_t addr);
|
||||||
jit_value_t ReadMemory(
|
// jit_value_t ReadMemory(
|
||||||
uint32_t cia, jit_value_t addr, uint32_t size, bool acquire = false);
|
// uint32_t cia, jit_value_t addr, uint32_t size, bool acquire = false);
|
||||||
void WriteMemory(
|
// void WriteMemory(
|
||||||
uint32_t cia, jit_value_t addr, uint32_t size, jit_value_t value,
|
// uint32_t cia, jit_value_t addr, uint32_t size, jit_value_t value,
|
||||||
bool release = false);
|
// bool release = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int MakeUserFunction();
|
// int MakeUserFunction();
|
||||||
int MakePresentImportFunction();
|
// int MakePresentImportFunction();
|
||||||
int MakeMissingImportFunction();
|
// int MakeMissingImportFunction();
|
||||||
|
|
||||||
void GenerateBasicBlocks();
|
// void GenerateBasicBlocks();
|
||||||
void GenerateSharedBlocks();
|
// void GenerateSharedBlocks();
|
||||||
int PrepareBasicBlock(sdb::FunctionBlock* block);
|
// int PrepareBasicBlock(sdb::FunctionBlock* block);
|
||||||
void GenerateBasicBlock(sdb::FunctionBlock* block);
|
// void GenerateBasicBlock(sdb::FunctionBlock* block);
|
||||||
void SetupLocals();
|
// void SetupLocals();
|
||||||
|
|
||||||
xe_memory_ref memory_;
|
xe_memory_ref memory_;
|
||||||
jit_context_t context_;
|
|
||||||
jit_type_t fn_signature_;
|
|
||||||
jit_type_t shim_signature_;
|
|
||||||
GlobalExports global_exports_;
|
GlobalExports global_exports_;
|
||||||
jit_type_t global_export_signature_2_;
|
|
||||||
jit_type_t global_export_signature_3_;
|
|
||||||
jit_type_t global_export_signature_4_;
|
|
||||||
|
|
||||||
sdb::FunctionSymbol* symbol_;
|
// jit_type_t fn_signature_;
|
||||||
jit_function_t fn_;
|
// jit_type_t shim_signature_;
|
||||||
sdb::FunctionBlock* fn_block_;
|
// jit_type_t global_export_signature_2_;
|
||||||
jit_label_t return_block_;
|
// jit_type_t global_export_signature_3_;
|
||||||
jit_label_t internal_indirection_block_;
|
// jit_type_t global_export_signature_4_;
|
||||||
jit_label_t external_indirection_block_;
|
|
||||||
|
|
||||||
std::map<uint32_t, jit_label_t> bbs_;
|
// sdb::FunctionSymbol* symbol_;
|
||||||
|
// jit_function_t fn_;
|
||||||
|
// sdb::FunctionBlock* fn_block_;
|
||||||
|
// jit_label_t return_block_;
|
||||||
|
// jit_label_t internal_indirection_block_;
|
||||||
|
// jit_label_t external_indirection_block_;
|
||||||
|
|
||||||
// Address of the instruction being generated.
|
// std::map<uint32_t, jit_label_t> bbs_;
|
||||||
uint32_t cia_;
|
|
||||||
|
|
||||||
ppc::InstrAccessBits access_bits_;
|
// // Address of the instruction being generated.
|
||||||
struct {
|
// uint32_t cia_;
|
||||||
jit_value_t indirection_target;
|
|
||||||
jit_value_t indirection_cia;
|
|
||||||
|
|
||||||
jit_value_t xer;
|
// ppc::InstrAccessBits access_bits_;
|
||||||
jit_value_t lr;
|
// struct {
|
||||||
jit_value_t ctr;
|
// jit_value_t indirection_target;
|
||||||
jit_value_t cr[8];
|
// jit_value_t indirection_cia;
|
||||||
jit_value_t gpr[32];
|
|
||||||
jit_value_t fpr[32];
|
// jit_value_t xer;
|
||||||
} locals_;
|
// jit_value_t lr;
|
||||||
|
// jit_value_t ctr;
|
||||||
|
// jit_value_t cr[8];
|
||||||
|
// jit_value_t gpr[32];
|
||||||
|
// jit_value_t fpr[32];
|
||||||
|
// } locals_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,44 +13,114 @@
|
||||||
#include <xenia/cpu/exec_module.h>
|
#include <xenia/cpu/exec_module.h>
|
||||||
#include <xenia/cpu/sdb.h>
|
#include <xenia/cpu/sdb.h>
|
||||||
|
|
||||||
|
#include <asmjit/asmjit.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
using namespace xe::cpu;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::sdb;
|
using namespace xe::cpu::sdb;
|
||||||
using namespace xe::cpu::x64;
|
using namespace xe::cpu::x64;
|
||||||
|
|
||||||
|
using namespace AsmJit;
|
||||||
|
|
||||||
|
|
||||||
X64JIT::X64JIT(xe_memory_ref memory, SymbolTable* sym_table) :
|
X64JIT::X64JIT(xe_memory_ref memory, SymbolTable* sym_table) :
|
||||||
JIT(memory, sym_table),
|
JIT(memory, sym_table),
|
||||||
context_(NULL), emitter_(NULL) {
|
emitter_(NULL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
X64JIT::~X64JIT() {
|
X64JIT::~X64JIT() {
|
||||||
delete emitter_;
|
delete emitter_;
|
||||||
if (context_) {
|
|
||||||
jit_context_destroy(context_);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int X64JIT::Setup() {
|
int X64JIT::Setup() {
|
||||||
int result_code = 1;
|
int result_code = 1;
|
||||||
|
|
||||||
// Shared libjit context.
|
XELOGCPU("Initializing x64 JIT backend...");
|
||||||
context_ = jit_context_create();
|
|
||||||
XEEXPECTNOTNULL(context_);
|
// Check processor for support.
|
||||||
|
result_code = CheckProcessor();
|
||||||
|
if (result_code) {
|
||||||
|
XELOGE("Processor check failed, aborting...");
|
||||||
|
}
|
||||||
|
XEEXPECTZERO(result_code);
|
||||||
|
|
||||||
// Create the emitter used to generate functions.
|
// Create the emitter used to generate functions.
|
||||||
emitter_ = new X64Emitter(memory_, context_);
|
emitter_ = new X64Emitter(memory_);
|
||||||
|
|
||||||
// Inject global functions/variables/etc.
|
|
||||||
XEEXPECTZERO(InjectGlobals());
|
|
||||||
|
|
||||||
result_code = 0;
|
result_code = 0;
|
||||||
XECLEANUP:
|
XECLEANUP:
|
||||||
return result_code;
|
return result_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int X64JIT::InjectGlobals() {
|
namespace {
|
||||||
|
struct BitDescription {
|
||||||
|
uint32_t mask;
|
||||||
|
const char* description;
|
||||||
|
};
|
||||||
|
static const BitDescription x86Features[] = {
|
||||||
|
{ kX86FeatureRdtsc , "RDTSC" },
|
||||||
|
{ kX86FeatureRdtscP , "RDTSCP" },
|
||||||
|
{ kX86FeatureCMov , "CMOV" },
|
||||||
|
{ kX86FeatureCmpXchg8B , "CMPXCHG8B" },
|
||||||
|
{ kX86FeatureCmpXchg16B , "CMPXCHG16B" },
|
||||||
|
{ kX86FeatureClFlush , "CLFLUSH" },
|
||||||
|
{ kX86FeaturePrefetch , "PREFETCH" },
|
||||||
|
{ kX86FeatureLahfSahf , "LAHF/SAHF" },
|
||||||
|
{ kX86FeatureFXSR , "FXSAVE/FXRSTOR" },
|
||||||
|
{ kX86FeatureFFXSR , "FXSAVE/FXRSTOR Optimizations" },
|
||||||
|
{ kX86FeatureMmx , "MMX" },
|
||||||
|
{ kX86FeatureMmxExt , "MMX Extensions" },
|
||||||
|
{ kX86Feature3dNow , "3dNow!" },
|
||||||
|
{ kX86Feature3dNowExt , "3dNow! Extensions" },
|
||||||
|
{ kX86FeatureSse , "SSE" },
|
||||||
|
{ kX86FeatureSse2 , "SSE2" },
|
||||||
|
{ kX86FeatureSse3 , "SSE3" },
|
||||||
|
{ kX86FeatureSsse3 , "SSSE3" },
|
||||||
|
{ kX86FeatureSse4A , "SSE4A" },
|
||||||
|
{ kX86FeatureSse41 , "SSE4.1" },
|
||||||
|
{ kX86FeatureSse42 , "SSE4.2" },
|
||||||
|
{ kX86FeatureAvx , "AVX" },
|
||||||
|
{ kX86FeatureMSse , "Misaligned SSE" },
|
||||||
|
{ kX86FeatureMonitorMWait , "MONITOR/MWAIT" },
|
||||||
|
{ kX86FeatureMovBE , "MOVBE" },
|
||||||
|
{ kX86FeaturePopCnt , "POPCNT" },
|
||||||
|
{ kX86FeatureLzCnt , "LZCNT" },
|
||||||
|
{ kX86FeaturePclMulDQ , "PCLMULDQ" },
|
||||||
|
{ kX86FeatureMultiThreading , "Multi-Threading" },
|
||||||
|
{ kX86FeatureExecuteDisableBit , "Execute-Disable Bit" },
|
||||||
|
{ kX86Feature64Bit , "64-Bit Processor" },
|
||||||
|
{ 0, NULL },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
int X64JIT::CheckProcessor() {
|
||||||
|
const CpuInfo* cpu = CpuInfo::getGlobal();
|
||||||
|
const X86CpuInfo* x86Cpu = static_cast<const X86CpuInfo*>(cpu);
|
||||||
|
XELOGCPU("Processor Info:");
|
||||||
|
XELOGCPU(" Vendor string : %s", cpu->getVendorString());
|
||||||
|
XELOGCPU(" Brand string : %s", cpu->getBrandString());
|
||||||
|
XELOGCPU(" Family : %u", cpu->getFamily());
|
||||||
|
XELOGCPU(" Model : %u", cpu->getModel());
|
||||||
|
XELOGCPU(" Stepping : %u", cpu->getStepping());
|
||||||
|
XELOGCPU(" Number of Processors : %u", cpu->getNumberOfProcessors());
|
||||||
|
XELOGCPU(" Features : 0x%08X", cpu->getFeatures());
|
||||||
|
XELOGCPU(" Bugs : 0x%08X", cpu->getBugs());
|
||||||
|
XELOGCPU(" Processor Type : %u", x86Cpu->getProcessorType());
|
||||||
|
XELOGCPU(" Brand Index : %u", x86Cpu->getBrandIndex());
|
||||||
|
XELOGCPU(" CL Flush Cache Line : %u", x86Cpu->getFlushCacheLineSize());
|
||||||
|
XELOGCPU(" Max logical Processors: %u", x86Cpu->getMaxLogicalProcessors());
|
||||||
|
XELOGCPU(" APIC Physical ID : %u", x86Cpu->getApicPhysicalId());
|
||||||
|
XELOGCPU(" Features:");
|
||||||
|
uint32_t mask = cpu->getFeatures();
|
||||||
|
for (const BitDescription* d = x86Features; d->mask; d++) {
|
||||||
|
if (mask & d->mask) {
|
||||||
|
XELOGCPU(" %s", d->description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(benvanik): ensure features we want are supported.
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,29 +135,29 @@ int X64JIT::UninitModule(ExecModule* module) {
|
||||||
int X64JIT::Execute(xe_ppc_state_t* ppc_state, FunctionSymbol* fn_symbol) {
|
int X64JIT::Execute(xe_ppc_state_t* ppc_state, FunctionSymbol* fn_symbol) {
|
||||||
XELOGCPU("Execute(%.8X): %s...", fn_symbol->start_address, fn_symbol->name());
|
XELOGCPU("Execute(%.8X): %s...", fn_symbol->start_address, fn_symbol->name());
|
||||||
|
|
||||||
// Check function.
|
// // Check function.
|
||||||
jit_function_t jit_fn = (jit_function_t)fn_symbol->impl_value;
|
// jit_function_t jit_fn = (jit_function_t)fn_symbol->impl_value;
|
||||||
if (!jit_fn) {
|
// if (!jit_fn) {
|
||||||
// Function hasn't been prepped yet - prep it.
|
// // Function hasn't been prepped yet - prep it.
|
||||||
if (emitter_->PrepareFunction(fn_symbol)) {
|
// if (emitter_->PrepareFunction(fn_symbol)) {
|
||||||
XELOGCPU("Execute(%.8X): unable to make function %s",
|
// XELOGCPU("Execute(%.8X): unable to make function %s",
|
||||||
fn_symbol->start_address, fn_symbol->name());
|
// fn_symbol->start_address, fn_symbol->name());
|
||||||
return 1;
|
// return 1;
|
||||||
}
|
// }
|
||||||
jit_fn = (jit_function_t)fn_symbol->impl_value;
|
// jit_fn = (jit_function_t)fn_symbol->impl_value;
|
||||||
XEASSERTNOTNULL(jit_fn);
|
// XEASSERTNOTNULL(jit_fn);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Call into the function. This will compile it if needed.
|
// // Call into the function. This will compile it if needed.
|
||||||
jit_nuint lr = ppc_state->lr;
|
// jit_nuint lr = ppc_state->lr;
|
||||||
void* args[] = {&ppc_state, &lr};
|
// void* args[] = {&ppc_state, &lr};
|
||||||
uint64_t return_value;
|
// uint64_t return_value;
|
||||||
int apply_result = jit_function_apply(jit_fn, (void**)&args, &return_value);
|
// int apply_result = jit_function_apply(jit_fn, (void**)&args, &return_value);
|
||||||
if (!apply_result) {
|
// if (!apply_result) {
|
||||||
XELOGCPU("Execute(%.8X): apply failed with %d",
|
// XELOGCPU("Execute(%.8X): apply failed with %d",
|
||||||
fn_symbol->start_address, apply_result);
|
// fn_symbol->start_address, apply_result);
|
||||||
return 1;
|
// return 1;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@
|
||||||
#include <xenia/cpu/sdb.h>
|
#include <xenia/cpu/sdb.h>
|
||||||
#include <xenia/cpu/x64/x64_emitter.h>
|
#include <xenia/cpu/x64/x64_emitter.h>
|
||||||
|
|
||||||
#include <jit/jit.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
|
@ -39,9 +37,8 @@ public:
|
||||||
sdb::FunctionSymbol* fn_symbol);
|
sdb::FunctionSymbol* fn_symbol);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int InjectGlobals();
|
int CheckProcessor();
|
||||||
|
|
||||||
jit_context_t context_;
|
|
||||||
X64Emitter* emitter_;
|
X64Emitter* emitter_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
2
third_party/asmjit.gypi
vendored
2
third_party/asmjit.gypi
vendored
|
|
@ -11,11 +11,13 @@
|
||||||
],
|
],
|
||||||
'defines': [
|
'defines': [
|
||||||
'ASMJIT_X64=',
|
'ASMJIT_X64=',
|
||||||
|
'ASMJIT_API=',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
'defines': [
|
'defines': [
|
||||||
'ASMJIT_X64=',
|
'ASMJIT_X64=',
|
||||||
|
'ASMJIT_API=',
|
||||||
],
|
],
|
||||||
|
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue