a32_emit_x64: Reduce mov code duplication in {Read,Write}Memory
This commit is contained in:
parent
aabd0d824d
commit
58b2c83944
1 changed files with 45 additions and 72 deletions
|
@ -904,6 +904,46 @@ static Xbyak::RegExp EmitVAddrLookup(BlockOfCode& code, RegAlloc& reg_alloc,
|
||||||
return page + tmp;
|
return page + tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<std::size_t bitsize>
|
||||||
|
static void EmitReadMemoryMov(BlockOfCode& code, const Xbyak::Reg64& value, const Xbyak::RegExp& addr) {
|
||||||
|
switch (bitsize) {
|
||||||
|
case 8:
|
||||||
|
code.movzx(value.cvt32(), code.byte[addr]);
|
||||||
|
return;
|
||||||
|
case 16:
|
||||||
|
code.movzx(value.cvt32(), word[addr]);
|
||||||
|
return;
|
||||||
|
case 32:
|
||||||
|
code.mov(value.cvt32(), dword[addr]);
|
||||||
|
return;
|
||||||
|
case 64:
|
||||||
|
code.mov(value, qword[addr]);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
ASSERT_FALSE("Invalid bitsize");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t bitsize>
|
||||||
|
static void EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, const Xbyak::Reg64& value) {
|
||||||
|
switch (bitsize) {
|
||||||
|
case 8:
|
||||||
|
code.mov(code.byte[addr], value.cvt8());
|
||||||
|
return;
|
||||||
|
case 16:
|
||||||
|
code.mov(word[addr], value.cvt16());
|
||||||
|
return;
|
||||||
|
case 32:
|
||||||
|
code.mov(dword[addr], value.cvt32());
|
||||||
|
return;
|
||||||
|
case 64:
|
||||||
|
code.mov(qword[addr], value);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
ASSERT_FALSE("Invalid bitsize");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<std::size_t bitsize>
|
template<std::size_t bitsize>
|
||||||
void A32EmitX64::ReadMemory(A32EmitContext& ctx, IR::Inst* inst) {
|
void A32EmitX64::ReadMemory(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
@ -936,26 +976,7 @@ void A32EmitX64::ReadMemory(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
if (const auto marker = ShouldFastmem(ctx, inst)) {
|
if (const auto marker = ShouldFastmem(ctx, inst)) {
|
||||||
const auto location = code.getCurr();
|
const auto location = code.getCurr();
|
||||||
|
EmitReadMemoryMov<bitsize>(code, value, r13 + vaddr);
|
||||||
switch (bitsize) {
|
|
||||||
case 8:
|
|
||||||
code.movzx(value.cvt32(), code.byte[r13 + vaddr]);
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
code.movzx(value.cvt32(), word[r13 + vaddr]);
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
code.mov(value.cvt32(), dword[r13 + vaddr]);
|
|
||||||
break;
|
|
||||||
case 64:
|
|
||||||
code.mov(value, qword[r13 + vaddr]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT_FALSE("Invalid bitsize");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.reg_alloc.DefineValue(inst, value);
|
|
||||||
|
|
||||||
fastmem_patch_info.emplace(
|
fastmem_patch_info.emplace(
|
||||||
Common::BitCast<u64>(location),
|
Common::BitCast<u64>(location),
|
||||||
|
@ -966,29 +987,14 @@ void A32EmitX64::ReadMemory(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ctx.reg_alloc.DefineValue(inst, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Xbyak::Label abort, end;
|
Xbyak::Label abort, end;
|
||||||
|
|
||||||
const auto src_ptr = EmitVAddrLookup(code, ctx.reg_alloc, config, abort, vaddr, value);
|
const auto src_ptr = EmitVAddrLookup(code, ctx.reg_alloc, config, abort, vaddr, value);
|
||||||
switch (bitsize) {
|
EmitReadMemoryMov<bitsize>(code, value, src_ptr);
|
||||||
case 8:
|
|
||||||
code.movzx(value.cvt32(), code.byte[src_ptr]);
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
code.movzx(value.cvt32(), word[src_ptr]);
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
code.mov(value.cvt32(), dword[src_ptr]);
|
|
||||||
break;
|
|
||||||
case 64:
|
|
||||||
code.mov(value, qword[src_ptr]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT_FALSE("Invalid bitsize");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
code.jmp(end);
|
code.jmp(end);
|
||||||
code.L(abort);
|
code.L(abort);
|
||||||
code.call(wrapped_fn);
|
code.call(wrapped_fn);
|
||||||
|
@ -1029,24 +1035,7 @@ void A32EmitX64::WriteMemory(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
if (const auto marker = ShouldFastmem(ctx, inst)) {
|
if (const auto marker = ShouldFastmem(ctx, inst)) {
|
||||||
const auto location = code.getCurr();
|
const auto location = code.getCurr();
|
||||||
|
EmitWriteMemoryMov<bitsize>(code, r13 + vaddr, value);
|
||||||
switch (bitsize) {
|
|
||||||
case 8:
|
|
||||||
code.mov(code.byte[r13 + vaddr], value.cvt8());
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
code.mov(word[r13 + vaddr], value.cvt16());
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
code.mov(dword[r13 + vaddr], value.cvt32());
|
|
||||||
break;
|
|
||||||
case 64:
|
|
||||||
code.mov(qword[r13 + vaddr], value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT_FALSE("Invalid bitsize");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fastmem_patch_info.emplace(
|
fastmem_patch_info.emplace(
|
||||||
Common::BitCast<u64>(location),
|
Common::BitCast<u64>(location),
|
||||||
|
@ -1063,23 +1052,7 @@ void A32EmitX64::WriteMemory(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
Xbyak::Label abort, end;
|
Xbyak::Label abort, end;
|
||||||
|
|
||||||
const auto dest_ptr = EmitVAddrLookup(code, ctx.reg_alloc, config, abort, vaddr);
|
const auto dest_ptr = EmitVAddrLookup(code, ctx.reg_alloc, config, abort, vaddr);
|
||||||
switch (bitsize) {
|
EmitWriteMemoryMov<bitsize>(code, dest_ptr, value);
|
||||||
case 8:
|
|
||||||
code.mov(code.byte[dest_ptr], value.cvt8());
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
code.mov(word[dest_ptr], value.cvt16());
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
code.mov(dword[dest_ptr], value.cvt32());
|
|
||||||
break;
|
|
||||||
case 64:
|
|
||||||
code.mov(qword[dest_ptr], value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT_FALSE("Invalid bitsize");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
code.jmp(end);
|
code.jmp(end);
|
||||||
code.L(abort);
|
code.L(abort);
|
||||||
code.call(wrapped_fn);
|
code.call(wrapped_fn);
|
||||||
|
|
Loading…
Reference in a new issue