Alignment option in xmm read/write.

This commit is contained in:
Ben Vanik 2013-10-06 10:25:41 -07:00
parent 26e22e2b16
commit cdb13775e2
1 changed files with 14 additions and 2 deletions

View File

@ -1877,8 +1877,10 @@ XmmVar X64Emitter::ReadMemoryXmm(
// Align memory address. // Align memory address.
GpVar aligned_addr(c.newGpVar()); GpVar aligned_addr(c.newGpVar());
c.mov(aligned_addr, addr); c.mov(aligned_addr, addr);
bool aligned = false;
switch (alignment) { switch (alignment) {
case 4: case 4:
aligned = true;
c.and_(aligned_addr, imm(~0xF)); c.and_(aligned_addr, imm(~0xF));
break; break;
default: default:
@ -1890,7 +1892,11 @@ XmmVar X64Emitter::ReadMemoryXmm(
GpVar real_address = TouchMemoryAddress(cia, aligned_addr); GpVar real_address = TouchMemoryAddress(cia, aligned_addr);
XmmVar value(c.newXmmVar()); XmmVar value(c.newXmmVar());
if (aligned) {
c.movaps(value, xmmword_ptr(real_address)); c.movaps(value, xmmword_ptr(real_address));
} else {
c.movups(value, xmmword_ptr(real_address));
}
// Byte swap. // Byte swap.
GpVar byte_swap_addr(c.newGpVar()); GpVar byte_swap_addr(c.newGpVar());
@ -1952,9 +1958,11 @@ void X64Emitter::WriteMemoryXmm(
// Align memory address. // Align memory address.
GpVar aligned_addr(c.newGpVar()); GpVar aligned_addr(c.newGpVar());
c.mov(aligned_addr, addr); c.mov(aligned_addr, addr);
bool aligned = false;
switch (alignment) { switch (alignment) {
case 4: case 4:
c.and_(aligned_addr, imm(~0xF)); c.and_(aligned_addr, imm(~0xF));
aligned = true;
break; break;
default: default:
XEASSERTALWAYS(); XEASSERTALWAYS();
@ -1970,7 +1978,11 @@ void X64Emitter::WriteMemoryXmm(
c.mov(byte_swap_addr, imm((sysint_t)&__xmm_byte_swap)); c.mov(byte_swap_addr, imm((sysint_t)&__xmm_byte_swap));
c.pshufb(value, xmmword_ptr(byte_swap_addr)); c.pshufb(value, xmmword_ptr(byte_swap_addr));
if (aligned) {
c.movaps(xmmword_ptr(real_address), value); c.movaps(xmmword_ptr(real_address), value);
} else {
c.movups(xmmword_ptr(real_address), value);
}
} }
GpVar X64Emitter::get_uint64(uint64_t value) { GpVar X64Emitter::get_uint64(uint64_t value) {