Xmm read/write cleanup.
This commit is contained in:
parent
9ebbc3535f
commit
e5ca996a08
|
@ -1869,43 +1869,6 @@ GpVar X64Emitter::ReadMemory(
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __m128i __xmm_byte_swap = _mm_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
|
|
||||||
XmmVar X64Emitter::ReadMemoryXmm(
|
|
||||||
uint32_t cia, GpVar& addr, uint32_t alignment) {
|
|
||||||
X86Compiler& c = compiler_;
|
|
||||||
|
|
||||||
// Align memory address.
|
|
||||||
GpVar aligned_addr(c.newGpVar());
|
|
||||||
c.mov(aligned_addr, addr);
|
|
||||||
bool aligned = false;
|
|
||||||
switch (alignment) {
|
|
||||||
case 4:
|
|
||||||
aligned = true;
|
|
||||||
c.and_(aligned_addr, imm(~0xF));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
XEASSERTALWAYS();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rebase off of memory base pointer.
|
|
||||||
GpVar real_address = TouchMemoryAddress(cia, aligned_addr);
|
|
||||||
|
|
||||||
XmmVar value(c.newXmmVar());
|
|
||||||
if (aligned) {
|
|
||||||
c.movaps(value, xmmword_ptr(real_address));
|
|
||||||
} else {
|
|
||||||
c.movups(value, xmmword_ptr(real_address));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Byte swap.
|
|
||||||
GpVar byte_swap_addr(c.newGpVar());
|
|
||||||
c.mov(byte_swap_addr, imm((sysint_t)&__xmm_byte_swap));
|
|
||||||
c.pshufb(value, xmmword_ptr(byte_swap_addr));
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void X64Emitter::WriteMemory(
|
void X64Emitter::WriteMemory(
|
||||||
uint32_t cia, GpVar& addr, uint32_t size, GpVar& value,
|
uint32_t cia, GpVar& addr, uint32_t size, GpVar& value,
|
||||||
bool release) {
|
bool release) {
|
||||||
|
@ -1951,6 +1914,49 @@ void X64Emitter::WriteMemory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __m128i __xmm_byte_swap = _mm_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
|
||||||
|
void X64Emitter::ByteSwapXmm(XmmVar& value) {
|
||||||
|
X86Compiler& c = compiler_;
|
||||||
|
// TODO(benvanik): clone value before modifying it?
|
||||||
|
GpVar byte_swap_addr(c.newGpVar());
|
||||||
|
c.mov(byte_swap_addr, imm((sysint_t)&__xmm_byte_swap));
|
||||||
|
c.pshufb(value, xmmword_ptr(byte_swap_addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
XmmVar X64Emitter::ReadMemoryXmm(
|
||||||
|
uint32_t cia, GpVar& addr, uint32_t alignment) {
|
||||||
|
X86Compiler& c = compiler_;
|
||||||
|
|
||||||
|
// Align memory address.
|
||||||
|
GpVar aligned_addr(c.newGpVar());
|
||||||
|
c.mov(aligned_addr, addr);
|
||||||
|
bool aligned = false;
|
||||||
|
switch (alignment) {
|
||||||
|
case 4:
|
||||||
|
aligned = true;
|
||||||
|
c.and_(aligned_addr, imm(~0xF));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
XEASSERTALWAYS();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebase off of memory base pointer.
|
||||||
|
GpVar real_address = TouchMemoryAddress(cia, aligned_addr);
|
||||||
|
|
||||||
|
XmmVar value(c.newXmmVar());
|
||||||
|
if (aligned) {
|
||||||
|
c.movaps(value, xmmword_ptr(real_address));
|
||||||
|
} else {
|
||||||
|
c.movups(value, xmmword_ptr(real_address));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Byte swap.
|
||||||
|
ByteSwapXmm(value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
void X64Emitter::WriteMemoryXmm(
|
void X64Emitter::WriteMemoryXmm(
|
||||||
uint32_t cia, GpVar& addr, uint32_t alignment, XmmVar& value) {
|
uint32_t cia, GpVar& addr, uint32_t alignment, XmmVar& value) {
|
||||||
X86Compiler& c = compiler_;
|
X86Compiler& c = compiler_;
|
||||||
|
@ -1973,10 +1979,7 @@ void X64Emitter::WriteMemoryXmm(
|
||||||
GpVar real_address = TouchMemoryAddress(cia, aligned_addr);
|
GpVar real_address = TouchMemoryAddress(cia, aligned_addr);
|
||||||
|
|
||||||
// Byte swap.
|
// Byte swap.
|
||||||
// TODO(benvanik): clone value before modifying it?
|
ByteSwapXmm(value);
|
||||||
GpVar byte_swap_addr(c.newGpVar());
|
|
||||||
c.mov(byte_swap_addr, imm((sysint_t)&__xmm_byte_swap));
|
|
||||||
c.pshufb(value, xmmword_ptr(byte_swap_addr));
|
|
||||||
|
|
||||||
if (aligned) {
|
if (aligned) {
|
||||||
c.movaps(xmmword_ptr(real_address), value);
|
c.movaps(xmmword_ptr(real_address), value);
|
||||||
|
|
|
@ -105,11 +105,12 @@ public:
|
||||||
AsmJit::GpVar TouchMemoryAddress(uint32_t cia, AsmJit::GpVar& addr);
|
AsmJit::GpVar TouchMemoryAddress(uint32_t cia, AsmJit::GpVar& addr);
|
||||||
AsmJit::GpVar ReadMemory(
|
AsmJit::GpVar ReadMemory(
|
||||||
uint32_t cia, AsmJit::GpVar& addr, uint32_t size, bool acquire = false);
|
uint32_t cia, AsmJit::GpVar& addr, uint32_t size, bool acquire = false);
|
||||||
AsmJit::XmmVar ReadMemoryXmm(
|
|
||||||
uint32_t cia, AsmJit::GpVar& addr, uint32_t alignment);
|
|
||||||
void WriteMemory(
|
void WriteMemory(
|
||||||
uint32_t cia, AsmJit::GpVar& addr, uint32_t size, AsmJit::GpVar& value,
|
uint32_t cia, AsmJit::GpVar& addr, uint32_t size, AsmJit::GpVar& value,
|
||||||
bool release = false);
|
bool release = false);
|
||||||
|
void ByteSwapXmm(AsmJit::XmmVar& value);
|
||||||
|
AsmJit::XmmVar ReadMemoryXmm(
|
||||||
|
uint32_t cia, AsmJit::GpVar& addr, uint32_t alignment);
|
||||||
void WriteMemoryXmm(
|
void WriteMemoryXmm(
|
||||||
uint32_t cia, AsmJit::GpVar& addr, uint32_t alignment,
|
uint32_t cia, AsmJit::GpVar& addr, uint32_t alignment,
|
||||||
AsmJit::XmmVar& value);
|
AsmJit::XmmVar& value);
|
||||||
|
|
Loading…
Reference in New Issue