Add psrlq and paddb + tests

This commit is contained in:
Afonso Bordado 2019-09-25 20:43:46 +00:00
parent c6f071d37d
commit b301237ac6
4 changed files with 113 additions and 4 deletions

View File

@ -40,7 +40,7 @@ if(USE_FLOAT)
add_definitions(-DUSE_FLOAT)
endif()
add_definitions(-g -std=gnu99 -funwind-tables -O3 -fvisibility=hidden)
add_definitions(-g -std=gnu99 -funwind-tables -O0 -fvisibility=hidden)
if(USE_CCACHE)
find_program(CCACHE_FOUND ccache)
@ -218,6 +218,7 @@ file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c")
foreach(file ${extension_tests})
get_filename_component(testname "${file}" NAME_WE)
add_executable(${testname} ${file})
set_target_properties(${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/extensions/")
set_target_properties(${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests/extensions/")
target_compile_options(${testname} PRIVATE "-mmmx")
add_test(NAME "${testname}" COMMAND "${CMAKE_BINARY_DIR}/${BOX86}" "${CMAKE_BINARY_DIR}/tests/extensions/${testname}")
endforeach()

View File

@ -877,6 +877,14 @@
emu->regs[tmp8s].dword[0] = __builtin_bswap32(emu->regs[tmp8s].dword[0]);
NEXT;
_0f_0xD3: /* PSRLQ Gm,Em */
nextop = F8;
GET_EM;
for(int i=0; i<4; ++i) {
GM.q >>= EM->q;
}
NEXT;
_0f_0xD5: /* PMULLW Gm,Em */
nextop = F8;
GET_EM;
@ -926,6 +934,13 @@
GM.uw[i] -= EM->uw[i];
NEXT;
_0f_0xFC: /* PADDW mm, mm */
nextop = F8;
GET_EM;
for(int i=0; i<8; ++i)
GM.sb[i] += EM->sb[i];
NEXT;
_0f_0xFD: /* PADDW Gm,Em */
nextop = F8;
GET_EM;

View File

@ -121,12 +121,12 @@ int Run(x86emu_t *emu)
&&_default, &&_default, &&_0f_0xBA, &&_0f_0xBB, &&_0f_0xBC, &&_0f_0xBD, &&_0f_0xBE, &&_0f_0xBF,
&&_0f_0xC0, &&_0f_0xC1, &&_0f_0xC2, &&_default, &&_0f_0xC4, &&_0f_0xC5, &&_0f_0xC6, &&_0f_0xC7,
&&_0f_0xC8, &&_0f_0xC9, &&_0f_0xCA, &&_0f_0xCB, &&_0f_0xCC, &&_0f_0xCD, &&_0f_0xCE, &&_0f_0xCF, //0xC8-0xCF
&&_default, &&_default, &&_default, &&_default, &&_default ,&&_0f_0xD5, &&_default, &&_default, //0xD0-0xD7
&&_default, &&_default, &&_default, &&_0f_0xD3, &&_default ,&&_0f_0xD5, &&_default, &&_default, //0xD0-0xD7
&&_default, &&_default, &&_default, &&_default, &&_default ,&&_default, &&_default, &&_default, //0xD8-0xDF
&&_default, &&_default, &&_default, &&_default, &&_default ,&&_0f_0xE5, &&_default, &&_default, //0xE0-0xE7
&&_default, &&_default, &&_default, &&_default, &&_default ,&&_0f_0xED, &&_default, &&_0f_0xEF, //0xE8-0xEF
&&_default, &&_default, &&_default, &&_default, &&_default ,&&_default, &&_0f_0xF6, &&_default, //0xF0-0xF7
&&_default, &&_0f_0xF9, &&_default, &&_default, &&_default ,&&_0f_0xFD, &&_default, &&_default //0xF8-0xFF
&&_default, &&_0f_0xF9, &&_default, &&_default, &&_0f_0xFC ,&&_0f_0xFD, &&_default, &&_default //0xF8-0xFF
};
static const void* opcodes66[256] = {

View File

@ -1,7 +1,97 @@
#include<stdint.h>
#include<stdio.h>
#include<stdbool.h>
#include<limits.h>
#include<immintrin.h>
#include<cpuid.h>
typedef uint8_t u8;
typedef int8_t i8;
typedef uint16_t u16;
typedef int16_t i16;
typedef uint32_t u32;
typedef int32_t i32;
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define I8_MAX 127
#define I8_MIN -128
#define U8_MAX 255
#define U8_MIN 0
#define I16_MAX 32767
#define I16_MIN -32768
#define U16_MAX 65535
#define U16_MIN 0
#define I32_MAX 2147483647
#define I32_MIN -2147483648
#define U32_MAX 4294967295
#define U32_MIN 0
#define MMX_TEST_STRUCT(sz) \
typedef struct mmx_##sz##_test { \
sz a; \
sz b; \
sz result; \
} mmx_##sz##_test_t
MMX_TEST_STRUCT(u8);
MMX_TEST_STRUCT(i8);
MMX_TEST_STRUCT(u16);
MMX_TEST_STRUCT(i16);
MMX_TEST_STRUCT(u32);
MMX_TEST_STRUCT(i32);
// Binary compare two mm registers
bool mm_raw_compare(__m64 a, __m64 b) {
__m64 a_upper_reg = _mm_srli_si64(a, 32);
__m64 b_upper_reg = _mm_srli_si64(b, 32);
int a_lower = _m_to_int(a);
int a_upper = _m_to_int(a_upper_reg);
int b_lower = _m_to_int(b);
int b_upper = _m_to_int(b_upper_reg);
return (a_lower == b_lower) && (a_upper == b_upper);
}
#define MMX_ARITH_TEST(name, testcases, testcase_type, type, size, testfunc) \
bool name() { \
printf("TEST: " #name "\n"); \
int errors = 0; \
\
for (size_t i = 0; i < ARRAY_SIZE(testcases); i++ ) { \
testcase_type test_data = testcases[i]; \
\
__m64 a = _mm_set1_pi##size(test_data.a); \
__m64 b = _mm_set1_pi##size(test_data.b); \
__m64 expected = _mm_set1_pi##size(test_data.result); \
__m64 result = testfunc(a, b); \
\
bool success = mm_raw_compare(expected, result); \
errors += (int) (!success); \
} \
\
_mm_empty(); \
printf("TEST: finished with: %d errors\n", errors); \
return errors; \
}
mmx_i8_test_t mmx_i8_add_test_data[] = {
{ .a = 1, .b = 2, .result = 3 },
{ .a = 0, .b = 1, .result = 1 },
{ .a = I8_MAX, .b = 1, .result = I8_MIN },
{ .a = I8_MIN, .b = -1, .result = I8_MAX },
{ .a = 0, .b = U8_MAX, .result = U8_MAX },
};
MMX_ARITH_TEST(test_mmx_add_pi8, mmx_i8_add_test_data, mmx_i8_test_t, i8, 8, _mm_add_pi8);
bool test_mmx_cpuid() {
printf("TEST: test_mmx_cpuid\n");
@ -22,8 +112,11 @@ bool test_mmx_cpuid() {
int main() {
int errors = 0;
errors += (int) test_mmx_cpuid();
errors += (int) test_mmx_add_pi8();
printf("Errors: %d\n", errors);
return errors;
}