Skip to content

Commit 528da1e

Browse files
committed
[x64] Support SysV ABI in emitter
Add support for the SysV ABI in the x64 emitter backend by using the appropriate registers for argument passing. Since the SysV ABI has less preserved registers than the Microsoft x64 ABI, reduce by 2 the number of General Purpose Registers (GPR) available to the emitter, so they can be used for the Context and Membase saved registers.
1 parent 4d514c8 commit 528da1e

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

src/xenia/cpu/backend/x64/x64_emitter.cc

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ static const size_t kStashOffset = 32;
6060

6161
const uint32_t X64Emitter::gpr_reg_map_[X64Emitter::GPR_COUNT] = {
6262
Xbyak::Operand::RBX, Xbyak::Operand::R10, Xbyak::Operand::R11,
63-
Xbyak::Operand::R12, Xbyak::Operand::R13, Xbyak::Operand::R14,
64-
Xbyak::Operand::R15,
63+
Xbyak::Operand::R12, Xbyak::Operand::R13,
64+
#if XE_PLATFORM_WIN32
65+
Xbyak::Operand::R14, Xbyak::Operand::R15,
66+
#endif
6567
};
6668

6769
const uint32_t X64Emitter::xmm_reg_map_[X64Emitter::XMM_COUNT] = {
@@ -469,7 +471,11 @@ void X64Emitter::CallIndirect(const hir::Instr* instr,
469471
} else {
470472
// Old-style resolve.
471473
// Not too important because indirection table is almost always available.
474+
#if XE_PLATFORM_WIN32
472475
mov(edx, reg.cvt32());
476+
#else
477+
mov(esi, reg.cvt32());
478+
#endif
473479
mov(rax, reinterpret_cast<uint64_t>(ResolveFunction));
474480
mov(GetNativeReg(0), GetContextReg());
475481
call(rax);
@@ -582,6 +588,7 @@ void X64Emitter::SetReturnAddress(uint64_t value) {
582588
}
583589

584590
Xbyak::Reg64 X64Emitter::GetNativeReg(uint32_t reg) {
591+
#if XE_PLATFORM_WIN32
585592
if (reg == 0)
586593
return rcx;
587594
else if (reg == 1)
@@ -593,15 +600,41 @@ Xbyak::Reg64 X64Emitter::GetNativeReg(uint32_t reg) {
593600

594601
assert_always();
595602
return r9;
603+
#else
604+
if (reg == 0)
605+
return rdi;
606+
else if (reg == 1)
607+
return rsi;
608+
else if (reg == 2)
609+
return rdx;
610+
else if (reg == 3)
611+
return rcx;
612+
613+
assert_always();
614+
return rcx;
615+
#endif
596616
}
597617

598618
Xbyak::Reg64 X64Emitter::GetNativeParam(uint32_t param) {
599619
return GetNativeReg(param + 1);
600620
}
601621

602622
// Important: If you change these, you must update the thunks in x64_backend.cc!
603-
Xbyak::Reg64 X64Emitter::GetContextReg() { return rsi; }
604-
Xbyak::Reg64 X64Emitter::GetMembaseReg() { return rdi; }
623+
Xbyak::Reg64 X64Emitter::GetContextReg() {
624+
#if XE_PLATFORM_WIN32
625+
return rsi;
626+
#else
627+
return r14;
628+
#endif
629+
}
630+
631+
Xbyak::Reg64 X64Emitter::GetMembaseReg() {
632+
#if XE_PLATFORM_WIN32
633+
return rdi;
634+
#else
635+
return r15;
636+
#endif
637+
}
605638

606639
void X64Emitter::ReloadContext() {
607640
mov(GetContextReg(), qword[rsp + StackLayout::GUEST_CTX_HOME]);

src/xenia/cpu/backend/x64/x64_emitter.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,23 @@ class X64Emitter : public Xbyak::CodeGenerator {
161161
std::vector<SourceMapEntry>* out_source_map);
162162

163163
public:
164+
#if XE_PLATFORM_WIN32
164165
// Reserved: rsp, rsi, rdi
165166
// Scratch: rax/rcx/rdx
166167
// xmm0-2
167168
// Available: rbx, r10-r15
168169
// xmm4-xmm15 (save to get xmm3)
169170
static const int GPR_COUNT = 7;
170171
static const int XMM_COUNT = 12;
172+
#else
173+
// Reserved: rsp, r14, r15
174+
// Scratch: rax/rdi/rsi/rcx/rdx
175+
// xmm0-2
176+
// Available: rbx, r10-r13
177+
// xmm4-xmm15 (save to get xmm3)
178+
static const int GPR_COUNT = 5;
179+
static const int XMM_COUNT = 12;
180+
#endif
171181

172182
static void SetupReg(const hir::Value* v, Xbyak::Reg8& r) {
173183
auto idx = gpr_reg_map_[v->reg.index];

0 commit comments

Comments
 (0)