forked from suyu/suyu
commit
a8ac99b619
2 changed files with 36 additions and 73 deletions
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
namespace Common::X64 {
|
namespace Common::X64 {
|
||||||
|
|
||||||
inline int RegToIndex(const Xbyak::Reg& reg) {
|
inline std::size_t RegToIndex(const Xbyak::Reg& reg) {
|
||||||
using Kind = Xbyak::Reg::Kind;
|
using Kind = Xbyak::Reg::Kind;
|
||||||
ASSERT_MSG((reg.getKind() & (Kind::REG | Kind::XMM)) != 0,
|
ASSERT_MSG((reg.getKind() & (Kind::REG | Kind::XMM)) != 0,
|
||||||
"RegSet only support GPRs and XMM registers.");
|
"RegSet only support GPRs and XMM registers.");
|
||||||
|
@ -19,17 +19,17 @@ inline int RegToIndex(const Xbyak::Reg& reg) {
|
||||||
return reg.getIdx() + (reg.getKind() == Kind::REG ? 0 : 16);
|
return reg.getIdx() + (reg.getKind() == Kind::REG ? 0 : 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Xbyak::Reg64 IndexToReg64(int reg_index) {
|
inline Xbyak::Reg64 IndexToReg64(std::size_t reg_index) {
|
||||||
ASSERT(reg_index < 16);
|
ASSERT(reg_index < 16);
|
||||||
return Xbyak::Reg64(reg_index);
|
return Xbyak::Reg64(static_cast<int>(reg_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Xbyak::Xmm IndexToXmm(int reg_index) {
|
inline Xbyak::Xmm IndexToXmm(std::size_t reg_index) {
|
||||||
ASSERT(reg_index >= 16 && reg_index < 32);
|
ASSERT(reg_index >= 16 && reg_index < 32);
|
||||||
return Xbyak::Xmm(reg_index - 16);
|
return Xbyak::Xmm(static_cast<int>(reg_index - 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Xbyak::Reg IndexToReg(int reg_index) {
|
inline Xbyak::Reg IndexToReg(std::size_t reg_index) {
|
||||||
if (reg_index < 16) {
|
if (reg_index < 16) {
|
||||||
return IndexToReg64(reg_index);
|
return IndexToReg64(reg_index);
|
||||||
} else {
|
} else {
|
||||||
|
@ -151,9 +151,13 @@ constexpr size_t ABI_SHADOW_SPACE = 0;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void ABI_CalculateFrameSize(std::bitset<32> regs, size_t rsp_alignment,
|
struct ABIFrameInfo {
|
||||||
size_t needed_frame_size, s32* out_subtraction,
|
s32 subtraction;
|
||||||
s32* out_xmm_offset) {
|
s32 xmm_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline ABIFrameInfo ABI_CalculateFrameSize(std::bitset<32> regs, size_t rsp_alignment,
|
||||||
|
size_t needed_frame_size) {
|
||||||
const auto count = (regs & ABI_ALL_GPRS).count();
|
const auto count = (regs & ABI_ALL_GPRS).count();
|
||||||
rsp_alignment -= count * 8;
|
rsp_alignment -= count * 8;
|
||||||
size_t subtraction = 0;
|
size_t subtraction = 0;
|
||||||
|
@ -170,33 +174,28 @@ inline void ABI_CalculateFrameSize(std::bitset<32> regs, size_t rsp_alignment,
|
||||||
rsp_alignment -= subtraction;
|
rsp_alignment -= subtraction;
|
||||||
subtraction += rsp_alignment & 0xF;
|
subtraction += rsp_alignment & 0xF;
|
||||||
|
|
||||||
*out_subtraction = (s32)subtraction;
|
return ABIFrameInfo{static_cast<s32>(subtraction),
|
||||||
*out_xmm_offset = (s32)(subtraction - xmm_base_subtraction);
|
static_cast<s32>(subtraction - xmm_base_subtraction)};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bitset<32> regs,
|
inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bitset<32> regs,
|
||||||
size_t rsp_alignment, size_t needed_frame_size = 0) {
|
size_t rsp_alignment, size_t needed_frame_size = 0) {
|
||||||
s32 subtraction, xmm_offset;
|
auto frame_info = ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size);
|
||||||
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
|
|
||||||
for (std::size_t i = 0; i < regs.size(); ++i) {
|
for (std::size_t i = 0; i < regs.size(); ++i) {
|
||||||
if (regs[i] && ABI_ALL_GPRS[i]) {
|
if (regs[i] && ABI_ALL_GPRS[i]) {
|
||||||
code.push(IndexToReg64(static_cast<int>(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (subtraction != 0) {
|
|
||||||
code.sub(code.rsp, subtraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < regs.count(); i++) {
|
|
||||||
if (regs.test(i) & ABI_ALL_GPRS.test(i)) {
|
|
||||||
code.push(IndexToReg64(i));
|
code.push(IndexToReg64(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frame_info.subtraction != 0) {
|
||||||
|
code.sub(code.rsp, frame_info.subtraction);
|
||||||
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < regs.size(); ++i) {
|
for (std::size_t i = 0; i < regs.size(); ++i) {
|
||||||
if (regs[i] && ABI_ALL_XMMS[i]) {
|
if (regs[i] && ABI_ALL_XMMS[i]) {
|
||||||
code.movaps(code.xword[code.rsp + xmm_offset], IndexToXmm(static_cast<int>(i)));
|
code.movaps(code.xword[code.rsp + frame_info.xmm_offset], IndexToXmm(i));
|
||||||
xmm_offset += 0x10;
|
frame_info.xmm_offset += 0x10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,59 +204,23 @@ inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::b
|
||||||
|
|
||||||
inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bitset<32> regs,
|
inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bitset<32> regs,
|
||||||
size_t rsp_alignment, size_t needed_frame_size = 0) {
|
size_t rsp_alignment, size_t needed_frame_size = 0) {
|
||||||
s32 subtraction, xmm_offset;
|
auto frame_info = ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size);
|
||||||
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < regs.size(); ++i) {
|
for (std::size_t i = 0; i < regs.size(); ++i) {
|
||||||
if (regs[i] && ABI_ALL_XMMS[i]) {
|
if (regs[i] && ABI_ALL_XMMS[i]) {
|
||||||
code.movaps(IndexToXmm(static_cast<int>(i)), code.xword[code.rsp + xmm_offset]);
|
code.movaps(IndexToXmm(i), code.xword[code.rsp + frame_info.xmm_offset]);
|
||||||
xmm_offset += 0x10;
|
frame_info.xmm_offset += 0x10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subtraction != 0) {
|
if (frame_info.subtraction != 0) {
|
||||||
code.add(code.rsp, subtraction);
|
code.add(code.rsp, frame_info.subtraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GPRs need to be popped in reverse order
|
// GPRs need to be popped in reverse order
|
||||||
for (int i = 15; i >= 0; i--) {
|
for (std::size_t j = 0; j < regs.size(); ++j) {
|
||||||
if (regs[i]) {
|
const std::size_t i = regs.size() - j - 1;
|
||||||
code.pop(IndexToReg64(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t ABI_PushRegistersAndAdjustStackGPS(Xbyak::CodeGenerator& code, std::bitset<32> regs,
|
|
||||||
size_t rsp_alignment,
|
|
||||||
size_t needed_frame_size = 0) {
|
|
||||||
s32 subtraction, xmm_offset;
|
|
||||||
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < regs.size(); ++i) {
|
|
||||||
if (regs[i] && ABI_ALL_GPRS[i]) {
|
if (regs[i] && ABI_ALL_GPRS[i]) {
|
||||||
code.push(IndexToReg64(static_cast<int>(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subtraction != 0) {
|
|
||||||
code.sub(code.rsp, subtraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ABI_SHADOW_SPACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ABI_PopRegistersAndAdjustStackGPS(Xbyak::CodeGenerator& code, std::bitset<32> regs,
|
|
||||||
size_t rsp_alignment, size_t needed_frame_size = 0) {
|
|
||||||
s32 subtraction, xmm_offset;
|
|
||||||
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
|
|
||||||
|
|
||||||
if (subtraction != 0) {
|
|
||||||
code.add(code.rsp, subtraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
// GPRs need to be popped in reverse order
|
|
||||||
for (int i = 15; i >= 0; i--) {
|
|
||||||
if (regs[i]) {
|
|
||||||
code.pop(IndexToReg64(i));
|
code.pop(IndexToReg64(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,22 +295,22 @@ void MacroJITx64Impl::Compile_Read(Macro::Opcode opcode) {
|
||||||
sub(result, opcode.immediate * -1);
|
sub(result, opcode.immediate * -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Common::X64::ABI_PushRegistersAndAdjustStackGPS(*this, PersistentCallerSavedRegs(), 0);
|
Common::X64::ABI_PushRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0);
|
||||||
mov(Common::X64::ABI_PARAM1, qword[STATE]);
|
mov(Common::X64::ABI_PARAM1, qword[STATE]);
|
||||||
mov(Common::X64::ABI_PARAM2, RESULT);
|
mov(Common::X64::ABI_PARAM2, RESULT);
|
||||||
Common::X64::CallFarFunction(*this, &Read);
|
Common::X64::CallFarFunction(*this, &Read);
|
||||||
Common::X64::ABI_PopRegistersAndAdjustStackGPS(*this, PersistentCallerSavedRegs(), 0);
|
Common::X64::ABI_PopRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0);
|
||||||
mov(RESULT, Common::X64::ABI_RETURN.cvt32());
|
mov(RESULT, Common::X64::ABI_RETURN.cvt32());
|
||||||
Compile_ProcessResult(opcode.result_operation, opcode.dst);
|
Compile_ProcessResult(opcode.result_operation, opcode.dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tegra::MacroJITx64Impl::Compile_Send(Xbyak::Reg32 value) {
|
void Tegra::MacroJITx64Impl::Compile_Send(Xbyak::Reg32 value) {
|
||||||
Common::X64::ABI_PushRegistersAndAdjustStackGPS(*this, PersistentCallerSavedRegs(), 0);
|
Common::X64::ABI_PushRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0);
|
||||||
mov(Common::X64::ABI_PARAM1, qword[STATE]);
|
mov(Common::X64::ABI_PARAM1, qword[STATE]);
|
||||||
mov(Common::X64::ABI_PARAM2, METHOD_ADDRESS);
|
mov(Common::X64::ABI_PARAM2, METHOD_ADDRESS);
|
||||||
mov(Common::X64::ABI_PARAM3, value);
|
mov(Common::X64::ABI_PARAM3, value);
|
||||||
Common::X64::CallFarFunction(*this, &Send);
|
Common::X64::CallFarFunction(*this, &Send);
|
||||||
Common::X64::ABI_PopRegistersAndAdjustStackGPS(*this, PersistentCallerSavedRegs(), 0);
|
Common::X64::ABI_PopRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0);
|
||||||
|
|
||||||
Xbyak::Label dont_process{};
|
Xbyak::Label dont_process{};
|
||||||
// Get increment
|
// Get increment
|
||||||
|
@ -414,7 +414,7 @@ void MacroJITx64Impl::Compile() {
|
||||||
bool keep_executing = true;
|
bool keep_executing = true;
|
||||||
labels.fill(Xbyak::Label());
|
labels.fill(Xbyak::Label());
|
||||||
|
|
||||||
Common::X64::ABI_PushRegistersAndAdjustStackGPS(*this, Common::X64::ABI_ALL_CALLEE_SAVED, 8);
|
Common::X64::ABI_PushRegistersAndAdjustStack(*this, Common::X64::ABI_ALL_CALLEE_SAVED, 8);
|
||||||
// JIT state
|
// JIT state
|
||||||
mov(STATE, Common::X64::ABI_PARAM1);
|
mov(STATE, Common::X64::ABI_PARAM1);
|
||||||
mov(PARAMETERS, Common::X64::ABI_PARAM2);
|
mov(PARAMETERS, Common::X64::ABI_PARAM2);
|
||||||
|
@ -452,7 +452,7 @@ void MacroJITx64Impl::Compile() {
|
||||||
|
|
||||||
L(end_of_code);
|
L(end_of_code);
|
||||||
|
|
||||||
Common::X64::ABI_PopRegistersAndAdjustStackGPS(*this, Common::X64::ABI_ALL_CALLEE_SAVED, 8);
|
Common::X64::ABI_PopRegistersAndAdjustStack(*this, Common::X64::ABI_ALL_CALLEE_SAVED, 8);
|
||||||
ret();
|
ret();
|
||||||
ready();
|
ready();
|
||||||
program = getCode<ProgramType>();
|
program = getCode<ProgramType>();
|
||||||
|
|
Loading…
Reference in a new issue