early-access version 2637

This commit is contained in:
pineappleEA
2022-04-02 22:34:58 +02:00
parent 0d49569ca5
commit 0397c1ff98
10 changed files with 84 additions and 26 deletions

View File

@@ -75,6 +75,14 @@ void AxxEmitX64::EmitMemoryRead(AxxEmitContext& ctx, IR::Inst* inst) {
return;
}
if (ordered && bitsize == 128) {
// Required for atomic 128-bit loads/stores
ctx.reg_alloc.ScratchGpr(HostLoc::RAX);
ctx.reg_alloc.ScratchGpr(HostLoc::RBX);
ctx.reg_alloc.ScratchGpr(HostLoc::RCX);
ctx.reg_alloc.ScratchGpr(HostLoc::RDX);
}
const Xbyak::Reg64 vaddr = ctx.reg_alloc.UseGpr(args[0]);
const int value_idx = bitsize == 128 ? ctx.reg_alloc.ScratchXmm().getIdx() : ctx.reg_alloc.ScratchGpr().getIdx();
@@ -145,6 +153,14 @@ void AxxEmitX64::EmitMemoryWrite(AxxEmitContext& ctx, IR::Inst* inst) {
return;
}
if (ordered && bitsize == 128) {
// Required for atomic 128-bit loads/stores
ctx.reg_alloc.ScratchGpr(HostLoc::RAX);
ctx.reg_alloc.ScratchGpr(HostLoc::RBX);
ctx.reg_alloc.ScratchGpr(HostLoc::RCX);
ctx.reg_alloc.ScratchGpr(HostLoc::RDX);
}
const Xbyak::Reg64 vaddr = ctx.reg_alloc.UseGpr(args[0]);
const int value_idx = bitsize == 128
? ctx.reg_alloc.UseXmm(args[1]).getIdx()
@@ -303,7 +319,15 @@ void AxxEmitX64::EmitExclusiveReadMemoryInline(AxxEmitContext& ctx, IR::Inst* in
}
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const bool ordered = IsOrdered(args[1].GetImmediateAccType());
const bool ordered = true;
if (ordered && bitsize == 128) {
// Required for atomic 128-bit loads/stores
ctx.reg_alloc.ScratchGpr(HostLoc::RAX);
ctx.reg_alloc.ScratchGpr(HostLoc::RBX);
ctx.reg_alloc.ScratchGpr(HostLoc::RCX);
ctx.reg_alloc.ScratchGpr(HostLoc::RDX);
}
const Xbyak::Reg64 vaddr = ctx.reg_alloc.UseGpr(args[0]);
const int value_idx = bitsize == 128 ? ctx.reg_alloc.ScratchXmm().getIdx() : ctx.reg_alloc.ScratchGpr().getIdx();
@@ -370,7 +394,7 @@ void AxxEmitX64::EmitExclusiveWriteMemoryInline(AxxEmitContext& ctx, IR::Inst* i
}
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const bool ordered = IsOrdered(args[2].GetImmediateAccType());
const bool ordered = true;
const auto value = [&] {
if constexpr (bitsize == 128) {

View File

@@ -201,10 +201,13 @@ template<>
template<std::size_t bitsize>
const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::RegExp& addr, bool ordered) {
if (ordered) {
if constexpr (bitsize == 128) {
code.mfence();
} else {
if constexpr (bitsize != 128) {
code.xor_(Xbyak::Reg32{value_idx}, Xbyak::Reg32{value_idx});
} else {
code.xor_(eax, eax);
code.xor_(ebx, ebx);
code.xor_(ecx, ecx);
code.xor_(edx, edx);
}
const void* fastmem_location = code.getCurr();
@@ -215,7 +218,7 @@ const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::Reg
break;
case 16:
code.lock();
code.xadd(word[addr], Xbyak::Reg32{value_idx});
code.xadd(word[addr], Xbyak::Reg16{value_idx});
break;
case 32:
code.lock();
@@ -226,8 +229,16 @@ const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::Reg
code.xadd(qword[addr], Xbyak::Reg64{value_idx});
break;
case 128:
// TODO (HACK): Detect CPUs where this load is not atomic
code.movaps(Xbyak::Xmm{value_idx}, xword[addr]);
code.lock();
code.cmpxchg16b(xword[addr]);
if (code.HasHostFeature(HostFeature::SSE41)) {
code.movq(Xbyak::Xmm{value_idx}, rax);
code.pinsrq(Xbyak::Xmm{value_idx}, rdx, 1);
} else {
code.movq(Xbyak::Xmm{value_idx}, rax);
code.movq(xmm0, rdx);
code.punpcklqdq(Xbyak::Xmm{value_idx}, xmm0);
}
break;
default:
ASSERT_FALSE("Invalid bitsize");
@@ -261,6 +272,20 @@ const void* EmitReadMemoryMov(BlockOfCode& code, int value_idx, const Xbyak::Reg
template<std::size_t bitsize>
const void* EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int value_idx, bool ordered) {
if (ordered) {
if constexpr (bitsize == 128) {
code.xor_(eax, eax);
code.xor_(edx, edx);
if (code.HasHostFeature(HostFeature::SSE41)) {
code.movq(rbx, Xbyak::Xmm{value_idx});
code.pextrq(rcx, Xbyak::Xmm{value_idx}, 1);
} else {
code.movaps(xmm0, Xbyak::Xmm{value_idx});
code.movq(rbx, xmm0);
code.punpckhqdq(xmm0, xmm0);
code.movq(rcx, xmm0);
}
}
const void* fastmem_location = code.getCurr();
switch (bitsize) {
case 8:
@@ -275,10 +300,14 @@ const void* EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int
case 64:
code.xchg(qword[addr], Xbyak::Reg64{value_idx});
break;
case 128:
code.movaps(xword[addr], Xbyak::Xmm{value_idx});
code.mfence();
case 128: {
Xbyak::Label loop;
code.L(loop);
code.lock();
code.cmpxchg16b(xword[addr]);
code.jnz(loop);
break;
}
default:
ASSERT_FALSE("Invalid bitsize");
}