Add MMX Multiply instructions

This commit is contained in:
Afonso Bordado 2019-09-26 14:37:56 +00:00
parent 0285cd1522
commit 352da49fdc
3 changed files with 60 additions and 3 deletions

View File

@ -1005,6 +1005,18 @@
GM.q <<= EM->q;
NEXT;
_0f_0xF5: /* PMADDWD Gm, Em */
nextop = F8;
GET_EM;
for (int i=0; i<2; ++i) {
int offset = i * 2;
tmp32s = (int32_t)GM.sw[offset + 0] * EM->sw[offset + 0];
tmp32s2 = (int32_t)GM.sw[offset + 1] * EM->sw[offset + 1];
GM.sd[i] = tmp32s + tmp32s2;
}
NEXT;
_0f_0xF6: /* PSADBW Gm, Em */
nextop = F8;
GET_EM;

View File

@ -35,7 +35,7 @@ int Run(x86emu_t *emu)
uint16_t tmp16u, tmp16u2;
int16_t tmp16s;
uint32_t tmp32u, tmp32u2, tmp32u3;
int32_t tmp32s;
int32_t tmp32s, tmp32s2;
uint64_t tmp64u;
int64_t tmp64s;
uintptr_t ip, old_ip;
@ -125,7 +125,7 @@ int Run(x86emu_t *emu)
&&_0f_0xD8, &&_0f_0xD9, &&_default, &&_0f_0xDB, &&_0f_0xDC ,&&_0f_0xDD, &&_default, &&_0f_0xDF, //0xD8-0xDF
&&_default, &&_default, &&_default, &&_default, &&_default ,&&_0f_0xE5, &&_default, &&_default, //0xE0-0xE7
&&_0f_0xE8, &&_0f_0xE9, &&_default, &&_0f_0xEB, &&_0f_0xEC ,&&_0f_0xED, &&_default, &&_0f_0xEF, //0xE8-0xEF
&&_default, &&_default, &&_default, &&_0f_0xF3, &&_default ,&&_default, &&_0f_0xF6, &&_default, //0xF0-0xF7
&&_default, &&_default, &&_default, &&_0f_0xF3, &&_default ,&&_0f_0xF5, &&_0f_0xF6, &&_default, //0xF0-0xF7
&&_0f_0xF8, &&_0f_0xF9, &&_0f_0xFA, &&_default, &&_0f_0xFC ,&&_0f_0xFD, &&_0f_0xFE, &&_default //0xF8-0xFF
};

View File

@ -290,13 +290,54 @@ MMX_64_TEST(test_mmx_pxor, mmx_pxor_test_data, _m_pxor);
mmx_i16_test_t mmx_pmullw_test_data[] = {
{ .a = 10, .b = 10, .result = 100 },
{ .a = 32000, .b = 10, .result = 0xE200 },
{ .a = 20000, .b = 20000, .result = 0x8400 },
};
mmx_i16_test_t mmx_pmulhw_test_data[] = {
{ .a = 10, .b = 10, .result = 0 },
{ .a = 32000, .b = 10, .result = 4 },
{ .a = 20000, .b = 20000, .result = 0x17D7 },
};
mmx_u64_test_t mmx_pmaddwd_test_data[] = {
{ .a = 0x0000000100000001,
.b = 0x0000000100000001,
.result = 0x0000000100000001 },
{ .a = 0x0000000200000004,
.b = 0x0000000200000004,
.result = 0x0000000400000010 },
// TODO: This shows that there may be some internal rounding going on
{ .a = 0x000000007FFFFFFF,
.b = 0x000000007FFFFFFF,
.result = 0x000000003FFF0002 },
// -1 * -1 = 2
{ .a = 0x00000000FFFFFFFF,
.b = 0x00000000FFFFFFFF,
.result = 0x0000000000000002 },
};
MMX_ARITH_TEST(test_mmx_pmullw, mmx_pmullw_test_data, mmx_i16_test_t, i16, 16, _m_pmullw);
MMX_ARITH_TEST(test_mmx_pmulhw, mmx_pmulhw_test_data, mmx_i16_test_t, i16, 16, _m_pmulhw);
MMX_64_TEST(test_mmx_pmaddwd, mmx_pmaddwd_test_data, _m_pmaddwd);
bool test_mmx_cpuid() {
printf("TEST: test_mmx_cpuid\n");
unsigned int eax, ebx, ecx, edx;
asm volatile(
"cpuid"
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
: "a" (1), "c" (0)
);
@ -335,6 +376,10 @@ int main() {
errors += (int) test_mmx_pandn();
errors += (int) test_mmx_pxor();
errors += (int) test_mmx_pmullw();
errors += (int) test_mmx_pmulhw();
errors += (int) test_mmx_pmaddwd();
printf("Errors: %d\n", errors);
return errors;
}