/* AUTOGENERATED FILE, DO NOT EDIT */ /* * Copyright (C) 2016 Julian Aron Prenner * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include "evoasm-x64.h" #include "evoasm-log.h" static const char *_evoasm_log_tag = "x64"; evoasm_success_t evoasm_x64_get_features(uint64_t *features_) { evoasm_buf_t buf_; evoasm_buf_t *buf = &buf_; evoasm_x64_params_t params = {0}; bool retval = true; uint64_t features = 0; uint32_t vals[3][2] = {0}; evoasm_log_debug("Running CPUID..."); EVOASM_TRY(alloc_failed, evoasm_buf_init, buf, EVOASM_BUF_TYPE_MMAP, 512); EVOASM_TRY(enc_failed, evoasm_x64_emit_func_prolog, EVOASM_X64_ABI_SYSV, buf); EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, EVOASM_X64_REG_A); EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, 1); EVOASM_X64_ENC(mov_r32_imm32); EVOASM_X64_ENC(cpuid); { int64_t addr_imm; addr_imm = (int64_t)(uintptr_t) &vals[0][0]; EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, EVOASM_X64_REG_DI); EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, addr_imm); EVOASM_X64_ENC(mov_r64_imm64); EVOASM_X64_SET(EVOASM_X64_PARAM_REG1, EVOASM_X64_REG_D); EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, EVOASM_X64_REG_DI); EVOASM_X64_ENC(mov_rm32_r32); EVOASM_X64_UNSET(EVOASM_X64_PARAM_ADDR_SIZE); EVOASM_X64_UNSET(EVOASM_X64_PARAM_REG_BASE); } { int64_t addr_imm; addr_imm = (int64_t)(uintptr_t) &vals[0][1]; EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, EVOASM_X64_REG_DI); EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, addr_imm); EVOASM_X64_ENC(mov_r64_imm64); EVOASM_X64_SET(EVOASM_X64_PARAM_REG1, EVOASM_X64_REG_C); EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, EVOASM_X64_REG_DI); EVOASM_X64_ENC(mov_rm32_r32); EVOASM_X64_UNSET(EVOASM_X64_PARAM_ADDR_SIZE); EVOASM_X64_UNSET(EVOASM_X64_PARAM_REG_BASE); } EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, EVOASM_X64_REG_A); EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, 7); EVOASM_X64_ENC(mov_r32_imm32); EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, EVOASM_X64_REG_C); EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, 0); EVOASM_X64_ENC(mov_r32_imm32); EVOASM_X64_ENC(cpuid); { int64_t addr_imm; addr_imm = (int64_t)(uintptr_t) &vals[1][0]; EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, EVOASM_X64_REG_DI); EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, addr_imm); EVOASM_X64_ENC(mov_r64_imm64); EVOASM_X64_SET(EVOASM_X64_PARAM_REG1, EVOASM_X64_REG_B); EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, EVOASM_X64_REG_DI); EVOASM_X64_ENC(mov_rm32_r32); EVOASM_X64_UNSET(EVOASM_X64_PARAM_ADDR_SIZE); EVOASM_X64_UNSET(EVOASM_X64_PARAM_REG_BASE); } { int64_t addr_imm; addr_imm = (int64_t)(uintptr_t) &vals[1][1]; EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, EVOASM_X64_REG_DI); EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, addr_imm); EVOASM_X64_ENC(mov_r64_imm64); EVOASM_X64_SET(EVOASM_X64_PARAM_REG1, EVOASM_X64_REG_C); EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, EVOASM_X64_REG_DI); EVOASM_X64_ENC(mov_rm32_r32); EVOASM_X64_UNSET(EVOASM_X64_PARAM_ADDR_SIZE); EVOASM_X64_UNSET(EVOASM_X64_PARAM_REG_BASE); } EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, EVOASM_X64_REG_A); EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, 2147483649); EVOASM_X64_ENC(mov_r32_imm32); EVOASM_X64_ENC(cpuid); { int64_t addr_imm; addr_imm = (int64_t)(uintptr_t) &vals[2][0]; EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, EVOASM_X64_REG_DI); EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, addr_imm); EVOASM_X64_ENC(mov_r64_imm64); EVOASM_X64_SET(EVOASM_X64_PARAM_REG1, EVOASM_X64_REG_D); EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, EVOASM_X64_REG_DI); EVOASM_X64_ENC(mov_rm32_r32); EVOASM_X64_UNSET(EVOASM_X64_PARAM_ADDR_SIZE); EVOASM_X64_UNSET(EVOASM_X64_PARAM_REG_BASE); } { int64_t addr_imm; addr_imm = (int64_t)(uintptr_t) &vals[2][1]; EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, EVOASM_X64_REG_DI); EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, addr_imm); EVOASM_X64_ENC(mov_r64_imm64); EVOASM_X64_SET(EVOASM_X64_PARAM_REG1, EVOASM_X64_REG_C); EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, EVOASM_X64_REG_DI); EVOASM_X64_ENC(mov_rm32_r32); EVOASM_X64_UNSET(EVOASM_X64_PARAM_ADDR_SIZE); EVOASM_X64_UNSET(EVOASM_X64_PARAM_REG_BASE); } EVOASM_TRY(enc_failed, evoasm_x64_emit_func_epilog, EVOASM_X64_ABI_SYSV, buf); /*evoasm_buf_dump(buf, stderr);*/ EVOASM_TRY(enc_failed, evoasm_buf_protect, buf, EVOASM_MPROT_MODE_RX); evoasm_buf_exec(buf); if(vals[0][0] & (1ull << 8)) { features |= (1ull << EVOASM_X64_FEATURE_CX8); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "CX8" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " CX8" EVOASM_ANSI_CODE_RESET); } if(vals[0][0] & (1ull << 15)) { features |= (1ull << EVOASM_X64_FEATURE_CMOV); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "CMOV" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " CMOV" EVOASM_ANSI_CODE_RESET); } if(vals[0][0] & (1ull << 23)) { features |= (1ull << EVOASM_X64_FEATURE_MMX); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "MMX" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " MMX" EVOASM_ANSI_CODE_RESET); } if(vals[0][0] & (1ull << 25)) { features |= (1ull << EVOASM_X64_FEATURE_SSE); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "SSE" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " SSE" EVOASM_ANSI_CODE_RESET); } if(vals[0][0] & (1ull << 26)) { features |= (1ull << EVOASM_X64_FEATURE_SSE2); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "SSE2" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " SSE2" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 0)) { features |= (1ull << EVOASM_X64_FEATURE_SSE3); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "SSE3" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " SSE3" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 1)) { features |= (1ull << EVOASM_X64_FEATURE_PCLMULQDQ); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "PCLMULQDQ" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " PCLMULQDQ" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 9)) { features |= (1ull << EVOASM_X64_FEATURE_SSSE3); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "SSSE3" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " SSSE3" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 12)) { features |= (1ull << EVOASM_X64_FEATURE_FMA); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "FMA" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " FMA" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 13)) { features |= (1ull << EVOASM_X64_FEATURE_CX16); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "CX16" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " CX16" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 19)) { features |= (1ull << EVOASM_X64_FEATURE_SSE4_1); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "SSE4_1" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " SSE4_1" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 20)) { features |= (1ull << EVOASM_X64_FEATURE_SSE4_2); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "SSE4_2" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " SSE4_2" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 22)) { features |= (1ull << EVOASM_X64_FEATURE_MOVBE); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "MOVBE" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " MOVBE" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 23)) { features |= (1ull << EVOASM_X64_FEATURE_POPCNT); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "POPCNT" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " POPCNT" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 25)) { features |= (1ull << EVOASM_X64_FEATURE_AES); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "AES" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " AES" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 28)) { features |= (1ull << EVOASM_X64_FEATURE_AVX); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "AVX" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " AVX" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 29)) { features |= (1ull << EVOASM_X64_FEATURE_F16C); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "F16C" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " F16C" EVOASM_ANSI_CODE_RESET); } if(vals[0][1] & (1ull << 30)) { features |= (1ull << EVOASM_X64_FEATURE_RDRAND); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "RDRAND" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " RDRAND" EVOASM_ANSI_CODE_RESET); } if(vals[1][0] & (1ull << 3)) { features |= (1ull << EVOASM_X64_FEATURE_BMI1); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "BMI1" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " BMI1" EVOASM_ANSI_CODE_RESET); } if(vals[1][0] & (1ull << 5)) { features |= (1ull << EVOASM_X64_FEATURE_AVX2); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "AVX2" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " AVX2" EVOASM_ANSI_CODE_RESET); } if(vals[1][0] & (1ull << 8)) { features |= (1ull << EVOASM_X64_FEATURE_BMI2); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "BMI2" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " BMI2" EVOASM_ANSI_CODE_RESET); } if(vals[1][0] & (1ull << 11)) { features |= (1ull << EVOASM_X64_FEATURE_RTM); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "RTM" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " RTM" EVOASM_ANSI_CODE_RESET); } if(vals[1][0] & (1ull << 18)) { features |= (1ull << EVOASM_X64_FEATURE_RDSEED); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "RDSEED" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " RDSEED" EVOASM_ANSI_CODE_RESET); } if(vals[1][0] & (1ull << 19)) { features |= (1ull << EVOASM_X64_FEATURE_ADX); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "ADX" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " ADX" EVOASM_ANSI_CODE_RESET); } if(vals[1][0] & (1ull << 23)) { features |= (1ull << EVOASM_X64_FEATURE_CLFLUSHOPT); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "CLFLUSHOPT" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " CLFLUSHOPT" EVOASM_ANSI_CODE_RESET); } if(vals[1][0] & (1ull << 28)) { features |= (1ull << EVOASM_X64_FEATURE_SHA); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "SHA" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " SHA" EVOASM_ANSI_CODE_RESET); } if(vals[1][1] & (1ull << 0)) { features |= (1ull << EVOASM_X64_FEATURE_PREFETCHWT1); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "PREFETCHWT1" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " PREFETCHWT1" EVOASM_ANSI_CODE_RESET); } if(vals[2][1] & (1ull << 0)) { features |= (1ull << EVOASM_X64_FEATURE_LAHF_LM); evoasm_log_info("Found support for " EVOASM_ANSI_CODE_GREEN "LAHF_LM" EVOASM_ANSI_CODE_RESET); } else { evoasm_log_info("Missing support for " EVOASM_ANSI_CODE_RED " LAHF_LM" EVOASM_ANSI_CODE_RESET); } *features_ = features; cleanup: EVOASM_TRY(destroy_failed, evoasm_buf_destroy, buf); return retval; enc_failed: retval = false; goto cleanup; destroy_failed: return false; alloc_failed: return false; }