Implement movss xmm, xmm/m32

This commit is contained in:
Amaan Cheval 2017-11-30 17:11:33 +05:30 committed by Fabian
parent 662c3fb2d2
commit 7013405402
2 changed files with 51 additions and 6 deletions

View file

@ -402,6 +402,7 @@ const encodings = [
// - Missing are sse3+, and floating point
{ opcode: 0x0F10, e: 1 },
{ opcode: 0xF30F10, e: 1 },
{ opcode: 0x0F12, e: 1, skip: 1, },
{ opcode: 0x660F12, only_mem: 1, e: 1 },
{ opcode: 0xF20F12, e: 1, skip: 1, },

View file

@ -309,6 +309,20 @@ static void instr_0F10(union reg128 source, int32_t r) {
}
DEFINE_SSE_SPLIT(instr_0F10, safe_read128s, read_xmm128s)
static void instr_F30F10_reg(int32_t r1, int32_t r2) {
// movss xmm, xmm/m32
task_switch_test_mmx();
union reg128 data = read_xmm128s(r1);
union reg128 orig = read_xmm128s(r2);
write_xmm128(r2, data.u32[0], orig.u32[1], orig.u32[2], orig.u32[3]);
}
static void instr_F30F10_mem(int32_t addr, int32_t r) {
// movss xmm, xmm/m32
task_switch_test_mmx();
int32_t data = safe_read32s(addr);
write_xmm128(r, data, 0, 0, 0);
}
static void instr_0F11() { unimplemented_sse(); }
static void instr_0F12_mem(int32_t addr, int32_t r) { unimplemented_sse(); }
static void instr_0F12_reg(int32_t r1, int32_t r2) { unimplemented_sse(); }
@ -3481,13 +3495,28 @@ switch(opcode)
case 0x10:
{
int32_t modrm_byte = read_imm8();
if(modrm_byte < 0xC0)
int32_t prefixes_ = *prefixes;
if(prefixes_ & PREFIX_F3)
{
instr_0F10_mem(modrm_resolve(modrm_byte), modrm_byte >> 3 & 7);
if(modrm_byte < 0xC0)
{
instr_F30F10_mem(modrm_resolve(modrm_byte), modrm_byte >> 3 & 7);
}
else
{
instr_F30F10_reg(modrm_byte & 7, modrm_byte >> 3 & 7);
}
}
else
{
instr_0F10_reg(modrm_byte & 7, modrm_byte >> 3 & 7);
if(modrm_byte < 0xC0)
{
instr_0F10_mem(modrm_resolve(modrm_byte), modrm_byte >> 3 & 7);
}
else
{
instr_0F10_reg(modrm_byte & 7, modrm_byte >> 3 & 7);
}
}
}
break;
@ -7834,13 +7863,28 @@ switch(opcode)
case 0x10:
{
int32_t modrm_byte = read_imm8();
if(modrm_byte < 0xC0)
int32_t prefixes_ = *prefixes;
if(prefixes_ & PREFIX_F3)
{
instr_0F10_mem(modrm_resolve(modrm_byte), modrm_byte >> 3 & 7);
if(modrm_byte < 0xC0)
{
instr_F30F10_mem(modrm_resolve(modrm_byte), modrm_byte >> 3 & 7);
}
else
{
instr_F30F10_reg(modrm_byte & 7, modrm_byte >> 3 & 7);
}
}
else
{
instr_0F10_reg(modrm_byte & 7, modrm_byte >> 3 & 7);
if(modrm_byte < 0xC0)
{
instr_0F10_mem(modrm_resolve(modrm_byte), modrm_byte >> 3 & 7);
}
else
{
instr_0F10_reg(modrm_byte & 7, modrm_byte >> 3 & 7);
}
}
}
break;