#include "cpu_id.h"
#include "platform.h"
#include <library/cpp/testing/unittest/registar.h>
// There are no tests yet for instructions that use 512-bit wide registers because they are not
// supported by some compilers yet.
// Relevant review in LLVM https://reviews.llvm.org/D16757, we should wait untill it will be in our
// version of Clang.
//
// There are also no tests for PREFETCHWT1, PCOMMIT, CLFLUSHOPT and CLWB as they are not supported
// by our compilers yet (and there are no available processors yet :).
static void ExecuteSSEInstruction();
static void ExecuteSSE2Instruction();
static void ExecuteSSE3Instruction();
static void ExecuteSSSE3Instruction();
static void ExecuteSSE41Instruction();
static void ExecuteSSE42Instruction();
static void ExecuteF16CInstruction();
static void ExecuteAVXInstruction();
static void ExecuteAVX2Instruction();
static void ExecutePOPCNTInstruction();
static void ExecuteBMI1Instruction();
static void ExecuteBMI2Instruction();
static void ExecutePCLMULInstruction();
static void ExecuteAESInstruction();
static void ExecuteAVXInstruction();
static void ExecuteAVX2Instruction();
static void ExecuteAVX512FInstruction();
static void ExecuteAVX512DQInstruction();
static void ExecuteAVX512IFMAInstruction();
static void ExecuteAVX512PFInstruction();
static void ExecuteAVX512ERInstruction();
static void ExecuteAVX512CDInstruction();
static void ExecuteAVX512BWInstruction();
static void ExecuteAVX512VLInstruction();
static void ExecuteAVX512VBMIInstruction();
static void ExecutePREFETCHWT1Instruction();
static void ExecuteSHAInstruction();
static void ExecuteADXInstruction();
static void ExecuteRDRANDInstruction();
static void ExecuteRDSEEDInstruction();
static void ExecutePCOMMITInstruction();
static void ExecuteCLFLUSHOPTInstruction();
static void ExecuteCLWBInstruction();
static void ExecuteFMAInstruction() {
}
static void ExecuteRDTSCPInstruction() {
}
static void ExecuteXSAVEInstruction() {
}
static void ExecuteOSXSAVEInstruction() {
}
Y_UNIT_TEST_SUITE(TestCpuId) {
#define DECLARE_TEST_HAVE_INSTRUCTION(name) \
Y_UNIT_TEST(Test##Have##name) { \
if (NX86::Have##name()) { \
Execute##name##Instruction(); \
} \
}
Y_CPU_ID_ENUMERATE(DECLARE_TEST_HAVE_INSTRUCTION)
#undef DECLARE_TEST_HAVE_INSTRUCTION
Y_UNIT_TEST(TestSSE2) {
#if defined(_x86_64_)
UNIT_ASSERT(NX86::HaveSSE2());
#endif
}
Y_UNIT_TEST(TestCpuBrand) {
ui32 store[12];
//Cout << CpuBrand(store) << Endl;;
UNIT_ASSERT(strlen(CpuBrand(store)) > 0);
}
Y_UNIT_TEST(TestCachedAndNoncached) {
#define Y_DEF_NAME(X) UNIT_ASSERT_VALUES_EQUAL(NX86::Have##X(), NX86::CachedHave##X());
Y_CPU_ID_ENUMERATE(Y_DEF_NAME)
#undef Y_DEF_NAME
}
}
#if defined(_x86_64_)
#if defined(__GNUC__)
void ExecuteSSEInstruction() {
__asm__ __volatile__("xorps %%xmm0, %%xmm0\n"
:
:
: "xmm0");
}
void ExecuteSSE2Instruction() {
__asm__ __volatile__("psrldq $0, %%xmm0\n"
:
:
: "xmm0");
}
void ExecuteSSE3Instruction() {
__asm__ __volatile__("addsubpd %%xmm0, %%xmm0\n"
:
:
: "xmm0");
}
void ExecuteSSSE3Instruction() {
__asm__ __volatile__("psignb %%xmm0, %%xmm0\n"
:
:
: "xmm0");
}
void ExecuteSSE41Instruction() {
__asm__ __volatile__("pmuldq %%xmm0, %%xmm0\n"
:
:
: "xmm0");
}
void ExecuteSSE42Instruction() {
__asm__ __volatile__("crc32 %%eax, %%eax\n"
:
:
: "eax");
}
void ExecuteF16CInstruction() {
__asm__ __volatile__("vcvtph2ps %%xmm0, %%ymm0\n"
:
:
: "xmm0");
}
void ExecuteAVXInstruction() {
__asm__ __volatile__("vzeroupper\n"
:
:
: "xmm0");
}
void ExecuteAVX2Instruction() {
__asm__ __volatile__("vpunpcklbw %%ymm0, %%ymm0, %%ymm0\n"
:
:
: "xmm0");
}
void ExecutePOPCNTInstruction() {
__asm__ __volatile__("popcnt %%eax, %%eax\n"
:
:
: "eax");
}
void ExecuteBMI1Instruction() {
__asm__ __volatile__("tzcnt %%eax, %%eax\n"
:
:
: "eax");
}
void ExecuteBMI2Instruction() {
__asm__ __volatile__("pdep %%rax, %%rdi, %%rax\n"
:
:
: "rax");
}
void ExecutePCLMULInstruction() {
__asm__ __volatile__("pclmullqlqdq %%xmm0, %%xmm0\n"
:
:
: "xmm0");
}
void ExecuteAESInstruction() {
__asm__ __volatile__("aesimc %%xmm0, %%xmm0\n"
:
:
: "xmm0");
}
void ExecuteAVX512FInstruction() {
}
void ExecuteAVX512DQInstruction() {
}
void ExecuteAVX512IFMAInstruction() {
}
void ExecuteAVX512PFInstruction() {
}
void ExecuteAVX512ERInstruction() {
}
void ExecuteAVX512CDInstruction() {
}
void ExecuteAVX512BWInstruction() {
}
void ExecuteAVX512VLInstruction() {
}
void ExecuteAVX512VBMIInstruction() {
}
void ExecutePREFETCHWT1Instruction() {
}
void ExecuteSHAInstruction() {
__asm__ __volatile__("sha1msg1 %%xmm0, %%xmm0\n"
:
:
: "xmm0");
}
void ExecuteADXInstruction() {
__asm__ __volatile__("adcx %%eax, %%eax\n"
:
:
: "eax");
}
void ExecuteRDRANDInstruction() {
__asm__ __volatile__("rdrand %%eax"
:
:
: "eax");
}
void ExecuteRDSEEDInstruction() {
__asm__ __volatile__("rdseed %%eax"
:
:
: "eax");
}
void ExecutePCOMMITInstruction() {
}
void ExecuteCLFLUSHOPTInstruction() {
}
void ExecuteCLWBInstruction() {
}
#elif defined(_MSC_VER)
void ExecuteSSEInstruction() {
}
void ExecuteSSE2Instruction() {
}
void ExecuteSSE3Instruction() {
}
void ExecuteSSSE3Instruction() {
}
void ExecuteSSE41Instruction() {
}
void ExecuteSSE42Instruction() {
}
void ExecuteF16CInstruction() {
}
void ExecuteAVXInstruction() {
}
void ExecuteAVX2Instruction() {
}
void ExecutePOPCNTInstruction() {
}
void ExecuteBMI1Instruction() {
}
void ExecuteBMI2Instruction() {
}
void ExecutePCLMULInstruction() {
}
void ExecuteAESInstruction() {
}
void ExecuteAVX512FInstruction() {
}
void ExecuteAVX512DQInstruction() {
}
void ExecuteAVX512IFMAInstruction() {
}
void ExecuteAVX512PFInstruction() {
}
void ExecuteAVX512ERInstruction() {
}
void ExecuteAVX512CDInstruction() {
}
void ExecuteAVX512BWInstruction() {
}
void ExecuteAVX512VLInstruction() {
}
void ExecuteAVX512VBMIInstruction() {
}
void ExecutePREFETCHWT1Instruction() {
}
void ExecuteSHAInstruction() {
}
void ExecuteADXInstruction() {
}
void ExecuteRDRANDInstruction() {
}
void ExecuteRDSEEDInstruction() {
}
void ExecutePCOMMITInstruction() {
}
void ExecuteCLFLUSHOPTInstruction() {
}
void ExecuteCLWBInstruction() {
}
#else
#error "unknown compiler"
#endif
#else
void ExecuteSSEInstruction() {
}
void ExecuteSSE2Instruction() {
}
void ExecuteSSE3Instruction() {
}
void ExecuteSSSE3Instruction() {
}
void ExecuteSSE41Instruction() {
}
void ExecuteSSE42Instruction() {
}
void ExecuteF16CInstruction() {
}
void ExecuteAVXInstruction() {
}
void ExecuteAVX2Instruction() {
}
void ExecutePOPCNTInstruction() {
}
void ExecuteBMI1Instruction() {
}
void ExecuteBMI2Instruction() {
}
void ExecutePCLMULInstruction() {
}
void ExecuteAESInstruction() {
}
void ExecuteAVX512FInstruction() {
}
void ExecuteAVX512DQInstruction() {
}
void ExecuteAVX512IFMAInstruction() {
}
void ExecuteAVX512PFInstruction() {
}
void ExecuteAVX512ERInstruction() {
}
void ExecuteAVX512CDInstruction() {
}
void ExecuteAVX512BWInstruction() {
}
void ExecuteAVX512VLInstruction() {
}
void ExecuteAVX512VBMIInstruction() {
}
void ExecutePREFETCHWT1Instruction() {
}
void ExecuteSHAInstruction() {
}
void ExecuteADXInstruction() {
}
void ExecuteRDRANDInstruction() {
}
void ExecuteRDSEEDInstruction() {
}
void ExecutePCOMMITInstruction() {
}
void ExecuteCLFLUSHOPTInstruction() {
}
void ExecuteCLWBInstruction() {
}
#endif