2008-01-12 07:00:48 +00:00
|
|
|
#include "X86Assembler.h"
|
|
|
|
|
2008-06-23 01:35:05 +00:00
|
|
|
//------------------------------------------------
|
|
|
|
//Scalar Instructions
|
|
|
|
//------------------------------------------------
|
|
|
|
|
|
|
|
void CX86Assembler::MovssEd(const CAddress& address, XMMREGISTER registerId)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x11, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::MovssEd(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x10, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::AddssEd(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x58, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::SubssEd(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x5C, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::MulssEd(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x59, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::DivssEd(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x5E, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::RcpssEd(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x53, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::RsqrtssEd(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x52, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::SqrtssEd(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x51, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::CmpssEd(XMMREGISTER registerId, const CAddress& address, SSE_CMP_TYPE condition)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0xC2, address, registerId);
|
|
|
|
WriteByte(static_cast<uint8>(condition));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::Cvtsi2ssEd(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x2A, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::Cvttss2siEd(REGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEvGvOp(0x2C, false, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------
|
|
|
|
//Packed Instructions
|
|
|
|
//------------------------------------------------
|
|
|
|
|
2008-03-06 03:14:33 +00:00
|
|
|
void CX86Assembler::MovdVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x6E, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-01-12 07:00:48 +00:00
|
|
|
void CX86Assembler::MovdquVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x6F, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::MovdquVo(const CAddress& address, XMMREGISTER registerId)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x7F, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
void CX86Assembler::MovapsVo(const CAddress& address, XMMREGISTER registerId)
|
|
|
|
{
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x29, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-28 02:16:54 +00:00
|
|
|
void CX86Assembler::MovapsVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x28, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-03-16 22:31:37 +00:00
|
|
|
void CX86Assembler::PackssdwVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x6B, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::PackuswbVo(XMMREGISTER registerId, const CAddress& address)
|
2008-02-01 02:34:50 +00:00
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x67, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-08 22:07:28 +00:00
|
|
|
void CX86Assembler::PaddwVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0xFD, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-01-12 07:00:48 +00:00
|
|
|
void CX86Assembler::PandVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0xDB, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
void CX86Assembler::PandnVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0xDF, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-01-12 07:00:48 +00:00
|
|
|
void CX86Assembler::PcmpeqdVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x76, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-08 22:07:28 +00:00
|
|
|
void CX86Assembler::PcmpgtwVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x65, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-01 02:34:50 +00:00
|
|
|
void CX86Assembler::PmaxswVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0xEE, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::PminswVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0xEA, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-01-12 07:00:48 +00:00
|
|
|
void CX86Assembler::PorVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0xEB, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-10 23:08:04 +00:00
|
|
|
void CX86Assembler::PsllwVo(XMMREGISTER registerId, uint8 amount)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteVrOp(0x71, 0x06, registerId);
|
|
|
|
WriteByte(amount);
|
|
|
|
}
|
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
void CX86Assembler::PslldVo(XMMREGISTER registerId, uint8 amount)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteVrOp(0x72, 0x06, registerId);
|
|
|
|
WriteByte(amount);
|
|
|
|
}
|
|
|
|
|
2008-02-10 23:08:04 +00:00
|
|
|
void CX86Assembler::PsrawVo(XMMREGISTER registerId, uint8 amount)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteVrOp(0x71, 0x04, registerId);
|
|
|
|
WriteByte(amount);
|
|
|
|
}
|
|
|
|
|
2008-03-16 22:31:37 +00:00
|
|
|
void CX86Assembler::PsradVo(XMMREGISTER registerId, uint8 amount)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteVrOp(0x72, 0x04, registerId);
|
|
|
|
WriteByte(amount);
|
|
|
|
}
|
|
|
|
|
2008-02-01 02:34:50 +00:00
|
|
|
void CX86Assembler::PsrlwVo(XMMREGISTER registerId, uint8 amount)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteVrOp(0x71, 0x02, registerId);
|
|
|
|
WriteByte(amount);
|
|
|
|
}
|
|
|
|
|
2008-03-06 03:14:33 +00:00
|
|
|
void CX86Assembler::PsrldVo(XMMREGISTER registerId, uint8 amount)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteVrOp(0x72, 0x02, registerId);
|
|
|
|
WriteByte(amount);
|
|
|
|
}
|
|
|
|
|
2008-01-12 07:00:48 +00:00
|
|
|
void CX86Assembler::PsubbVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0xF8, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-01-15 20:27:44 +00:00
|
|
|
void CX86Assembler::PsubdVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0xFA, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-08 22:07:28 +00:00
|
|
|
void CX86Assembler::PunpcklbwVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x60, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
void CX86Assembler::PunpcklwdVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x61, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-29 02:11:27 +00:00
|
|
|
void CX86Assembler::PunpckldqVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x62, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-08 22:07:28 +00:00
|
|
|
void CX86Assembler::PunpckhbwVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x68, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-29 02:11:27 +00:00
|
|
|
void CX86Assembler::PunpckhdqVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x6A, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-01-12 07:00:48 +00:00
|
|
|
void CX86Assembler::PxorVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x66);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0xEF, address, registerId);
|
|
|
|
}
|
2008-02-27 02:23:28 +00:00
|
|
|
|
|
|
|
void CX86Assembler::AddpsVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x58, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-06-09 00:06:58 +00:00
|
|
|
void CX86Assembler::DivpsVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x5E, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-03-16 22:31:37 +00:00
|
|
|
void CX86Assembler::Cvtdq2psVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x5B, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-03-06 03:14:33 +00:00
|
|
|
void CX86Assembler::Cvttps2dqVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0xF3);
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x5B, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-03-15 16:20:36 +00:00
|
|
|
void CX86Assembler::MaxpsVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x5F, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::MinpsVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x5D, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-28 02:16:54 +00:00
|
|
|
void CX86Assembler::MulpsVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x59, address, registerId);
|
|
|
|
}
|
|
|
|
|
2008-02-27 02:23:28 +00:00
|
|
|
void CX86Assembler::SubpsVo(XMMREGISTER registerId, const CAddress& address)
|
|
|
|
{
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0x5C, address, registerId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::ShufpsVo(XMMREGISTER registerId, const CAddress& address, uint8 shuffleByte)
|
|
|
|
{
|
|
|
|
WriteByte(0x0F);
|
|
|
|
WriteEdVdOp(0xC6, address, registerId);
|
|
|
|
WriteByte(shuffleByte);
|
|
|
|
}
|
2008-06-23 01:35:05 +00:00
|
|
|
|
|
|
|
//------------------------------------------------
|
|
|
|
//Addressing utils
|
|
|
|
//------------------------------------------------
|
|
|
|
|
|
|
|
void CX86Assembler::WriteEdVdOp(uint8 opcode, const CAddress& address, XMMREGISTER xmmRegisterId)
|
|
|
|
{
|
|
|
|
REGISTER registerId = static_cast<REGISTER>(xmmRegisterId);
|
|
|
|
WriteRexByte(false, address, registerId);
|
|
|
|
CAddress NewAddress(address);
|
|
|
|
NewAddress.ModRm.nFnReg = registerId;
|
|
|
|
WriteByte(opcode);
|
|
|
|
NewAddress.Write(m_WriteFunction);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CX86Assembler::WriteVrOp(uint8 opcode, uint8 subOpcode, XMMREGISTER registerId)
|
|
|
|
{
|
|
|
|
CAddress address(MakeXmmRegisterAddress(registerId));
|
|
|
|
WriteRexByte(false, address);
|
|
|
|
address.ModRm.nFnReg = subOpcode;
|
|
|
|
WriteByte(opcode);
|
|
|
|
address.Write(m_WriteFunction);
|
|
|
|
}
|