mirror of
https://github.com/danog/ir.git
synced 2024-11-30 04:39:43 +01:00
Merge pull request #21 from weltling/cpuid
[RFC] cpu: Add framework for CPU feature handling
This commit is contained in:
commit
d26099c5ac
3
Makefile
3
Makefile
@ -41,7 +41,8 @@ endif
|
|||||||
OBJS_COMMON = $(BUILD_DIR)/ir.o $(BUILD_DIR)/ir_strtab.o $(BUILD_DIR)/ir_cfg.o \
|
OBJS_COMMON = $(BUILD_DIR)/ir.o $(BUILD_DIR)/ir_strtab.o $(BUILD_DIR)/ir_cfg.o \
|
||||||
$(BUILD_DIR)/ir_sccp.o $(BUILD_DIR)/ir_gcm.o $(BUILD_DIR)/ir_ra.o $(BUILD_DIR)/ir_emit.o \
|
$(BUILD_DIR)/ir_sccp.o $(BUILD_DIR)/ir_gcm.o $(BUILD_DIR)/ir_ra.o $(BUILD_DIR)/ir_emit.o \
|
||||||
$(BUILD_DIR)/ir_load.o $(BUILD_DIR)/ir_save.o $(BUILD_DIR)/ir_emit_c.o $(BUILD_DIR)/ir_dump.o \
|
$(BUILD_DIR)/ir_load.o $(BUILD_DIR)/ir_save.o $(BUILD_DIR)/ir_emit_c.o $(BUILD_DIR)/ir_dump.o \
|
||||||
$(BUILD_DIR)/ir_disasm.o $(BUILD_DIR)/ir_gdb.o $(BUILD_DIR)/ir_perf.o $(BUILD_DIR)/ir_check.o
|
$(BUILD_DIR)/ir_disasm.o $(BUILD_DIR)/ir_gdb.o $(BUILD_DIR)/ir_perf.o $(BUILD_DIR)/ir_check.o \
|
||||||
|
$(BUILD_DIR)/ir_cpuinfo.o
|
||||||
OBJS_IR = $(BUILD_DIR)/ir_main.o
|
OBJS_IR = $(BUILD_DIR)/ir_main.o
|
||||||
OBJS_IR_TEST = $(BUILD_DIR)/ir_test.o
|
OBJS_IR_TEST = $(BUILD_DIR)/ir_test.o
|
||||||
|
|
||||||
|
2
ir.h
2
ir.h
@ -768,6 +768,8 @@ int ir_mem_protect(void *ptr, size_t size);
|
|||||||
int ir_mem_unprotect(void *ptr, size_t size);
|
int ir_mem_unprotect(void *ptr, size_t size);
|
||||||
int ir_mem_flush(void *ptr, size_t size);
|
int ir_mem_flush(void *ptr, size_t size);
|
||||||
|
|
||||||
|
uint32_t ir_cpuinfo(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
61
ir_cpuinfo.c
Normal file
61
ir_cpuinfo.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* IR - Lightweight JIT Compilation Framework
|
||||||
|
* (CPU framework for x86)
|
||||||
|
* Copyright (C) 2023 by IR project.
|
||||||
|
* Authors: Anatol Belski <anbelski@linux.microsoft.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ir.h"
|
||||||
|
|
||||||
|
#if defined(IR_TARGET_X86) || defined(IR_TARGET_X64)
|
||||||
|
|
||||||
|
#include "ir_x86.h"
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
IR_ALWAYS_INLINE void ir_cpuid_ex(uint32_t info[4], uint32_t function, uint32_t index)
|
||||||
|
{
|
||||||
|
asm volatile("cpuid"
|
||||||
|
: "=a" (info[0]),
|
||||||
|
"=b" (info[1]),
|
||||||
|
"=c" (info[2]),
|
||||||
|
"=d" (info[3])
|
||||||
|
: "0" (function), "2" (index)
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
IR_ALWAYS_INLINE void ir_cpuid(uint32_t info[4], uint32_t function)
|
||||||
|
{
|
||||||
|
ir_cpuid_ex(info, function, 0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define ir_cpuid_ex __cpuidex
|
||||||
|
#define ir_cpuid __cpuid
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Intel SDM Vol. 2A */
|
||||||
|
uint32_t ir_cpuinfo(void)
|
||||||
|
{
|
||||||
|
uint32_t ret = 0;
|
||||||
|
uint32_t info_0x1[4] = {0}, info_0x7_0[4] = {0};
|
||||||
|
#define bit(mask, pos) (((mask) >> (pos)) & 1U)
|
||||||
|
|
||||||
|
ir_cpuid(info_0x1, 0x1);
|
||||||
|
if (bit(info_0x1[3], 26U)) ret |= IR_X86_SSE2;
|
||||||
|
if (bit(info_0x1[2], 0U)) ret |= IR_X86_SSE3;
|
||||||
|
if (bit(info_0x1[2], 9U)) ret |= IR_X86_SSSE3;
|
||||||
|
if (bit(info_0x1[2], 19U)) ret |= IR_X86_SSE41;
|
||||||
|
if (bit(info_0x1[2], 20U)) ret |= IR_X86_SSE42;
|
||||||
|
if (bit(info_0x1[2], 28U)) ret |= IR_X86_AVX;
|
||||||
|
|
||||||
|
ir_cpuid_ex(info_0x7_0, 0x7, 0);
|
||||||
|
if (bit(info_0x7_0[1], 5U)) ret |= IR_X86_AVX2;
|
||||||
|
|
||||||
|
#undef bit
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
uint32_t ir_cpuinfo(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* IR_TARGET_X86 || IR_TARGET_X64 */
|
12
ir_test.c
12
ir_test.c
@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
#include "ir.h"
|
#include "ir.h"
|
||||||
#include "ir_builder.h"
|
#include "ir_builder.h"
|
||||||
|
#if defined(IR_TARGET_X86) || defined(IR_TARGET_X64)
|
||||||
|
# include "ir_x86.h"
|
||||||
|
#endif
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
@ -94,6 +97,9 @@ int main(int argc, char **argv)
|
|||||||
int opt_level = 2;
|
int opt_level = 2;
|
||||||
uint32_t mflags = 0;
|
uint32_t mflags = 0;
|
||||||
uint64_t debug_regset = 0xffffffffffffffff;
|
uint64_t debug_regset = 0xffffffffffffffff;
|
||||||
|
#if defined(IR_TARGET_X86) || defined(IR_TARGET_X64)
|
||||||
|
uint32_t cpuinfo = ir_cpuinfo();
|
||||||
|
#endif
|
||||||
|
|
||||||
ir_consistency_check();
|
ir_consistency_check();
|
||||||
|
|
||||||
@ -109,6 +115,12 @@ int main(int argc, char **argv)
|
|||||||
/* pass */
|
/* pass */
|
||||||
}
|
}
|
||||||
} else if (strcmp(argv[i], "-mavx") == 0) {
|
} else if (strcmp(argv[i], "-mavx") == 0) {
|
||||||
|
#if defined(IR_TARGET_X86) || defined(IR_TARGET_X64)
|
||||||
|
if (!(cpuinfo & IR_X86_AVX)) {
|
||||||
|
fprintf(stderr, "ERROR: CPU doesn't support AVX instruction set)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
mflags |= IR_AVX;
|
mflags |= IR_AVX;
|
||||||
} else if (strcmp(argv[i], "-muse-fp") == 0) {
|
} else if (strcmp(argv[i], "-muse-fp") == 0) {
|
||||||
mflags |= IR_USE_FRAME_POINTER;
|
mflags |= IR_USE_FRAME_POINTER;
|
||||||
|
8
ir_x86.h
8
ir_x86.h
@ -221,4 +221,12 @@ struct _ir_target_constraints {
|
|||||||
int8_t hints[IR_MAX_REG_ARGS + 3];
|
int8_t hints[IR_MAX_REG_ARGS + 3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define IR_X86_SSE2 (1<<0)
|
||||||
|
#define IR_X86_SSE3 (1<<1)
|
||||||
|
#define IR_X86_SSSE3 (1<<2)
|
||||||
|
#define IR_X86_SSE41 (1<<3)
|
||||||
|
#define IR_X86_SSE42 (1<<4)
|
||||||
|
#define IR_X86_AVX (1<<5)
|
||||||
|
#define IR_X86_AVX2 (1<<6)
|
||||||
|
|
||||||
#endif /* IR_X86_H */
|
#endif /* IR_X86_H */
|
||||||
|
@ -65,7 +65,7 @@ LIBS=psapi.lib capstone.lib
|
|||||||
OBJS_COMMON=$(BUILD_DIR)\ir.obj $(BUILD_DIR)\ir_strtab.obj $(BUILD_DIR)\ir_cfg.obj \
|
OBJS_COMMON=$(BUILD_DIR)\ir.obj $(BUILD_DIR)\ir_strtab.obj $(BUILD_DIR)\ir_cfg.obj \
|
||||||
$(BUILD_DIR)\ir_sccp.obj $(BUILD_DIR)\ir_gcm.obj $(BUILD_DIR)\ir_ra.obj $(BUILD_DIR)\ir_emit.obj \
|
$(BUILD_DIR)\ir_sccp.obj $(BUILD_DIR)\ir_gcm.obj $(BUILD_DIR)\ir_ra.obj $(BUILD_DIR)\ir_emit.obj \
|
||||||
$(BUILD_DIR)\ir_load.obj $(BUILD_DIR)\ir_save.obj $(BUILD_DIR)\ir_emit_c.obj $(BUILD_DIR)\ir_dump.obj \
|
$(BUILD_DIR)\ir_load.obj $(BUILD_DIR)\ir_save.obj $(BUILD_DIR)\ir_emit_c.obj $(BUILD_DIR)\ir_dump.obj \
|
||||||
$(BUILD_DIR)\ir_disasm.obj $(BUILD_DIR)\ir_check.obj
|
$(BUILD_DIR)\ir_disasm.obj $(BUILD_DIR)\ir_check.obj $(BUILD_DIR)\ir_cpuinfo.obj
|
||||||
OBJS_IR = $(BUILD_DIR)\ir_main.obj
|
OBJS_IR = $(BUILD_DIR)\ir_main.obj
|
||||||
OBJS_IR_TEST = $(BUILD_DIR)\ir_test.obj
|
OBJS_IR_TEST = $(BUILD_DIR)\ir_test.obj
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user