I wanted a tiny scriptable meltdown proof way to run userspace programs and visualize how program execution impacts memory. It helps to explain how things like Actually Portable Executable works. It can show you how the GCC generated code is going about manipulating matrices and more. I didn't feel fully comfortable with Qemu and Bochs because I'm not smart enough to understand them. I wanted something like gVisor but with much stronger levels of assurances. I wanted a single binary that'll run, on all major operating systems with an embedded GPL barrier ZIP filesystem that is tiny enough to transpile to JavaScript and run in browsers too. https://justine.storage.googleapis.com/emulator625.mp4
263 lines
16 KiB
C
263 lines
16 KiB
C
#ifndef COSMOPOLITAN_LIBC_NEXGEN32E_X86FEATURE_H_
|
|
#define COSMOPOLITAN_LIBC_NEXGEN32E_X86FEATURE_H_
|
|
#include "libc/nexgen32e/kcpuids.h"
|
|
#include "libc/nexgen32e/x86compiler.h"
|
|
|
|
/**
|
|
* @fileoverview x86 cpu feature detection.
|
|
*/
|
|
|
|
#define X86_HAVE(FEATURE) _X86_HAVE(X86_##FEATURE)
|
|
|
|
/* clang-format off */
|
|
/* --- FEATURE LEAF REG BIT COMPILE-TIME-DEFINE HOOK */
|
|
#define X86_ACC 1H, EDX, 29, 0, _
|
|
#define X86_ACPI 1H, EDX, 22, 0, _
|
|
#define X86_ADX 7H, EBX, 19, _X86_CC_ADX, _ /* broadwell c. 2014 */
|
|
#define X86_AES 1H, ECX, 25, _X86_CC_AES, _ /* westmere c. 2010 */
|
|
#define X86_APIC 1H, EDX, 9, 0, _
|
|
#define X86_ARCH_CAPABILITIES 7H, EDX, 29, 0, _
|
|
#define X86_AVX 1H, ECX, 28, _X86_CC_AVX, AVX /* sandybridge c. 2012 */
|
|
#define X86_AVX2 7H, EBX, 5, _X86_CC_AVX2, AVX /* haswell c. 2013 */
|
|
#define X86_AVX512BW 7H, EBX, 30, 0, _
|
|
#define X86_AVX512CD 7H, EBX, 28, 0, _
|
|
#define X86_AVX512DQ 7H, EBX, 17, 0, _
|
|
#define X86_AVX512ER 7H, EBX, 27, 0, _
|
|
#define X86_AVX512F 7H, EBX, 16, 0, _
|
|
#define X86_AVX512IFMA 7H, EBX, 21, 0, _
|
|
#define X86_AVX512PF 7H, EBX, 26, 0, _
|
|
#define X86_AVX512VBMI 7H, ECX, 1, 0, _
|
|
#define X86_AVX512VL 7H, EBX, 31, 0, _
|
|
#define X86_AVX512_4FMAPS 7H, EDX, 3, 0, _
|
|
#define X86_AVX512_4VNNIW 7H, EDX, 2, 0, _
|
|
#define X86_AVX512_BF16 7H, EAX, 5, 0, _
|
|
#define X86_AVX512_BITALG 7H, ECX, 12, 0, _
|
|
#define X86_AVX512_VBMI2 7H, ECX, 6, 0, _
|
|
#define X86_AVX512_VNNI 7H, ECX, 11, 0, _
|
|
#define X86_AVX512_VP2INTERSECT 7H, EDX, 8, 0, _
|
|
#define X86_AVX512_VPOPCNTDQ 7H, ECX, 14, 0, _
|
|
#define X86_BMI 7H, EBX, 3, _X86_CC_BMI, _ /* haswell c. 2013 */
|
|
#define X86_BMI2 7H, EBX, 8, _X86_CC_BMI2, _ /* haswell c. 2013 */
|
|
#define X86_CID 1H, ECX, 10, 0, _
|
|
#define X86_CLDEMOTE 7H, ECX, 25, 0, _
|
|
#define X86_CLFLUSH 1H, EDX, 19, _X86_CC_SSE2, _
|
|
#define X86_CLFLUSHOPT 7H, EBX, 23, _X86_CC_CLFLUSHOPT, _ /* skylake/zen */
|
|
#define X86_CLWB 7H, EBX, 24, 0, _ /* skylake/zen2 */
|
|
#define X86_CMOV 1H, EDX, 15, 0, _
|
|
#define X86_CQM 7H, EBX, 12, 0, _
|
|
#define X86_CX16 1H, ECX, 13, 0, _
|
|
#define X86_CX8 1H, EDX, 8, 0, _
|
|
#define X86_DCA 1H, ECX, 18, 0, _
|
|
#define X86_DE 1H, EDX, 2, 0, _
|
|
#define X86_DS 1H, EDX, 21, 0, _
|
|
#define X86_DSCPL 1H, ECX, 4, 0, _
|
|
#define X86_DTES64 1H, ECX, 2, 0, _
|
|
#define X86_ERMS 7H, EBX, 9, 0, _ /* broaadwell c. 2014 */
|
|
#define X86_EST 1H, ECX, 7, 0, _
|
|
#define X86_F16C 1H, ECX, 29, 0, _
|
|
#define X86_FDP_EXCPTN_ONLY 7H, EBX, 6, 0, _
|
|
#define X86_FLUSH_L1D 7H, EDX, 28, 0, _
|
|
#define X86_FMA 1H, ECX, 12, _X86_CC_FMA, _ /* haswell c. 2013 */
|
|
#define X86_FPU 1H, EDX, 0, 0, _
|
|
#define X86_FSGSBASE 7H, EBX, 0, 0, _
|
|
#define X86_FXSR 1H, EDX, 24, 0, _
|
|
#define X86_GBPAGES 80000001H, EDX, 26, 0, _
|
|
#define X86_GFNI 7H, ECX, 8, 0, _
|
|
#define X86_HLE 7H, EBX, 4, 0, _
|
|
#define X86_HT 1H, EDX, 28, 0, _
|
|
#define X86_HYPERVISOR 1H, ECX, 31, 0, _
|
|
#define X86_IA64 1H, EDX, 30, 0, _
|
|
#define X86_INTEL_PT 7H, EBX, 25, 0, _
|
|
#define X86_INTEL_STIBP 7H, EDX, 27, 0, _
|
|
#define X86_INVPCID 1H, EBX, 10, 0, _
|
|
#define X86_INVTSC 80000007H, EDX, 8, _X86_CC_POPCNT, _ /* i.e. not a K8 */
|
|
#define X86_LA57 7H, ECX, 16, 0, _
|
|
#define X86_LAHF_LM 80000001H, ECX, 0, 0, _
|
|
#define X86_LM 80000001H, EDX, 29, 0, _
|
|
#define X86_MCA 1H, EDX, 14, 0, _
|
|
#define X86_MCE 1H, EDX, 7, 0, _
|
|
#define X86_MD_CLEAR 7H, EDX, 10, 0, _
|
|
#define X86_MMX 1H, EDX, 23, 0, _
|
|
#define X86_MOVBE 1H, ECX, 22, 0, _
|
|
#define X86_MOVDIR64B 7H, ECX, 28, 0, _
|
|
#define X86_MOVDIRI 7H, ECX, 27, 0, _
|
|
#define X86_MP 80000001H, EDX, 19, 0, _
|
|
#define X86_MPX 7H, EBX, 14, 0, _
|
|
#define X86_MSR 1H, EDX, 5, 0, _
|
|
#define X86_MTRR 1H, EDX, 12, 0, _
|
|
#define X86_MWAIT 1H, ECX, 3, 0, _
|
|
#define X86_NX 80000001H, EDX, 20, 0, _
|
|
#define X86_OSPKE 7H, ECX, 4, 0, _
|
|
#define X86_OSXSAVE 1H, ECX, 27, 0, _
|
|
#define X86_PAE 1H, EDX, 6, 0, _
|
|
#define X86_PAT 1H, EDX, 16, 0, _
|
|
#define X86_PBE 1H, EDX, 31, 0, _
|
|
#define X86_PCID 1H, ECX, 17, 0, _
|
|
#define X86_PCLMUL 1H, ECX, 1, _X86_CC_PCLMUL, _ /* westmere c. 2010 */
|
|
#define X86_PCONFIG 7H, EDX, 18, 0, _
|
|
#define X86_PDCM 1H, ECX, 15, 0, _
|
|
#define X86_PGE 1H, EDX, 13, 0, _
|
|
#define X86_PKU 7H, ECX, 3, 0, _
|
|
#define X86_PN 1H, EDX, 18, 0, _
|
|
#define X86_POPCNT 1H, ECX, 23, _X86_CC_POPCNT, _ /* nehalem c. 2008 */
|
|
#define X86_PSE 1H, EDX, 3, 0, _
|
|
#define X86_PSE36 1H, EDX, 17, 0, _
|
|
#define X86_RDPID 7H, ECX, 22, _X86_CC_RDPID, _ /* cannonlake c. 2018 */
|
|
#define X86_RDRND 1H, ECX, 30, _X86_CC_RDRND, _ /* ivybridge c. 2012 */
|
|
#define X86_RDSEED 7H, EBX, 18, _X86_CC_RDSEED, _ /* broadwell c. 2014 */
|
|
#define X86_RDTSCP 80000001H, EDX, 27, 0, _
|
|
#define X86_RDT_A 7H, EBX, 15, 0, _
|
|
#define X86_RTM 7H, EBX, 11, 0, _
|
|
#define X86_SDBG 1H, ECX, 11, 0, _
|
|
#define X86_SELFSNOOP 1H, EDX, 27, 0, _
|
|
#define X86_SEP 1H, EDX, 11, 0, _
|
|
#define X86_SHA 7H, EBX, 29, _X86_CC_SHA, _ /* goldmont (2016) */
|
|
#define X86_SMAP 7H, EBX, 20, 0, _
|
|
#define X86_SMEP 7H, EBX, 7, 0, _
|
|
#define X86_SMX 1H, ECX, 6, 0, _
|
|
#define X86_SPEC_CTRL 7H, EDX, 26, 0, _
|
|
#define X86_SPEC_CTRL_SSBD 7H, EDX, 31, 0, _
|
|
#define X86_SSE 1H, EDX, 25, _X86_CC_SSE, _ /* pentium c. 1999 */
|
|
#define X86_SSE2 1H, EDX, 26, _X86_CC_SSE2, _ /* pentium c. 2001 */
|
|
#define X86_SSE3 1H, ECX, 0, _X86_CC_SSE3, _ /* k8 c. 2005 */
|
|
#define X86_SSE4_1 1H, ECX, 19, _X86_CC_SSE4_1, _ /* core c. 2006 */
|
|
#define X86_SSE4_2 1H, ECX, 20, _X86_CC_SSE4_2, _ /* nehalem c. 2008 */
|
|
#define X86_SSSE3 1H, ECX, 9, _X86_CC_SSSE3, _ /* westmere c. 2010 */
|
|
#define X86_SYSCALL 80000001H, EDX, 11, 0, _
|
|
#define X86_TM2 1H, ECX, 8, 0, _
|
|
#define X86_TME 7H, ECX, 13, 0, _
|
|
#define X86_TSC 1H, EDX, 4, 0, _
|
|
#define X86_TSC_ADJUST 7H, EBX, 1, 0, _
|
|
#define X86_TSC_DEADLINE_TIMER 1H, ECX, 24, 0, _
|
|
#define X86_TSX_FORCE_ABORT 7H, EDX, 13, 0, _
|
|
#define X86_UMIP 7H, ECX, 2, 0, _
|
|
#define X86_VAES 7H, ECX, 9, 0, _
|
|
#define X86_VME 1H, EDX, 1, 0, _
|
|
#define X86_VMX 1H, ECX, 5, 0, _
|
|
#define X86_VPCLMULQDQ 7H, ECX, 10, 0, _
|
|
#define X86_WAITPKG 7H, ECX, 5, 0, _
|
|
#define X86_X2APIC 1H, ECX, 21, 0, _
|
|
#define X86_XSAVE 1H, ECX, 26, _X86_CC_XSAVE, _ /* sandybridge c. 2012 */
|
|
#define X86_XTPR 1H, ECX, 14, 0, _
|
|
#define X86_ZERO_FCS_FDS 7H, EBX, 13, 0, _
|
|
/* clang-format on */
|
|
|
|
/* AMD specific features */
|
|
#define X86_ABM 80000001H, ECX, 5, _X86_CC_ABM, _
|
|
#define X86_3DNOW 80000001H, EDX, 31, 0, _
|
|
#define X86_3DNOWEXT 80000001H, EDX, 30, 0, _
|
|
#define X86_3DNOWPREFETCH 80000001H, ECX, 8, 0, _
|
|
#define X86_BPEXT 80000001H, ECX, 26, 0, _
|
|
#define X86_CMP_LEGACY 80000001H, ECX, 1, 0, _
|
|
#define X86_CR8_LEGACY 80000001H, ECX, 4, 0, _
|
|
#define X86_EXTAPIC 80000001H, ECX, 3, 0, _
|
|
#define X86_FMA4 80000001H, ECX, 16, 0, _
|
|
#define X86_FXSR_OPT 80000001H, EDX, 25, 0, _
|
|
#define X86_IBS 80000001H, ECX, 10, 0, _
|
|
#define X86_LWP 80000001H, ECX, 15, 0, _
|
|
#define X86_MISALIGNSSE 80000001H, ECX, 7, 0, _
|
|
#define X86_MMXEXT 80000001H, EDX, 22, 0, _
|
|
#define X86_MWAITX 80000001H, ECX, 29, 0, _
|
|
#define X86_NODEID_MSR 80000001H, ECX, 19, 0, _
|
|
#define X86_OSVW 80000001H, ECX, 9, 0, _
|
|
#define X86_OVERFLOW_RECOV 80000007H, EBX, 0, 0, _
|
|
#define X86_PERFCTR_CORE 80000001H, ECX, 23, 0, _
|
|
#define X86_PERFCTR_LLC 80000001H, ECX, 28, 0, _
|
|
#define X86_PERFCTR_NB 80000001H, ECX, 24, 0, _
|
|
#define X86_PTSC 80000001H, ECX, 27, 0, _
|
|
#define X86_SKINIT 80000001H, ECX, 12, 0, _
|
|
#define X86_SMCA 80000007H, EBX, 3, 0, _
|
|
#define X86_SSE4A 80000001H, ECX, 6, 0, _
|
|
#define X86_SUCCOR 80000007H, EBX, 1, 0, _
|
|
#define X86_SVM 80000001H, ECX, 2, 0, _
|
|
#define X86_TBM 80000001H, ECX, 21, 0, _
|
|
#define X86_TCE 80000001H, ECX, 17, 0, _
|
|
#define X86_TOPOEXT 80000001H, ECX, 22, 0, _
|
|
#define X86_WDT 80000001H, ECX, 13, 0, _
|
|
#define X86_XOP 80000001H, ECX, 11, 0, _
|
|
|
|
/* Defined but not loaded by kCpuids.S */
|
|
#define X86_ARAT 6H, EAX, 2, 0, _
|
|
#define X86_AVIC 8000000AH, EDX, 13, 0, _
|
|
#define X86_CLZERO 80000008H, EBX, 0, 0, _
|
|
#define X86_DECODEASSISTS 8000000AH, EDX, 7, 0, _
|
|
#define X86_DTHERM 6H, EAX, 0, 0, _
|
|
#define X86_FLUSHBYASID 8000000AH, EDX, 6, 0, _
|
|
#define X86_HWP 6H, EAX, 7, 0, _
|
|
#define X86_HWP_ACT_WINDOW 6H, EAX, 9, 0, _
|
|
#define X86_HWP_EPP 6H, EAX, 10, 0, _
|
|
#define X86_HWP_NOTIFY 6H, EAX, 8, 0, _
|
|
#define X86_HWP_PKG_REQ 6H, EAX, 11, 0, _
|
|
#define X86_IBPB 80000008H, EBX, 12, 0, _
|
|
#define X86_IBRS 80000008H, EBX, 14, 0, _
|
|
#define X86_IDA 6H, EAX, 1, 0, _
|
|
#define X86_IRPERF 80000008H, EBX, 1, 0, _
|
|
#define X86_LBRV 8000000AH, EDX, 1, 0, _
|
|
#define X86_NPT 8000000AH, EDX, 0, 0, _
|
|
#define X86_NRIPS 8000000AH, EDX, 3, 0, _
|
|
#define X86_PAUSEFILTER 8000000AH, EDX, 10, 0, _
|
|
#define X86_PFTHRESHOLD 8000000AH, EDX, 12, 0, _
|
|
#define X86_PLN 6H, EAX, 4, 0, _
|
|
#define X86_PTS 6H, EAX, 6, 0, _
|
|
#define X86_SSBD 80000008H, EBX, 24, 0, _
|
|
#define X86_SSB_NO 80000008H, EBX, 26, 0, _
|
|
#define X86_STIBP 80000008H, EBX, 15, 0, _
|
|
#define X86_STIBP_ALWAYS_ON 80000008H, EBX, 17, 0, _
|
|
#define X86_SVML 8000000AH, EDX, 2, 0, _
|
|
#define X86_TSCRATEMSR 8000000AH, EDX, 4, 0, _
|
|
#define X86_VGIF 8000000AH, EDX, 16, 0, _
|
|
#define X86_VIRT_SSBD 80000008H, EBX, 25, 0, _
|
|
#define X86_VMCBCLEAN 8000000AH, EDX, 5, 0, _
|
|
#define X86_V_VMSAVE_VMLOAD 8000000AH, EDX, 15, 0, _
|
|
#define X86_WBNOINVD 80000008H, EBX, 9, 0, _
|
|
#define X86_XGETBV1 DH, EAX, 2, 0, _
|
|
#define X86_XSAVEC DH, EAX, 1, 0, _
|
|
#define X86_XSAVEERPTR 80000008H, EBX, 2, 0, _
|
|
#define X86_XSAVEOPT DH, EAX, 0, 0, _
|
|
#define X86_XSAVES DH, EAX, 3, 0, _
|
|
|
|
#define X86_NEED(FEATURE) _X86_NEED(X86_##FEATURE)
|
|
#define X86_WORD(FEATURE) _X86_WORD(X86_##FEATURE)
|
|
#define X86_LEAF(FEATURE) _X86_LEAF(X86_##FEATURE)
|
|
#define X86_REG(FEATURE) _X86_REG(X86_##FEATURE)
|
|
#define X86_BIT(FEATURE) _X86_BIT(X86_##FEATURE)
|
|
|
|
#define _X86_HAVE(FEATURE) __X86_HAVE(FEATURE)
|
|
#define _X86_NEED(FEATURE) __X86_NEED(FEATURE)
|
|
#define _X86_WORD(FEATURE) __X86_WORD(FEATURE)
|
|
#define _X86_LEAF(FEATURE) __X86_LEAF(FEATURE)
|
|
#define _X86_REG(FEATURE) __X86_REG(FEATURE)
|
|
#define _X86_BIT(FEATURE) __X86_BIT(FEATURE)
|
|
|
|
#define __X86_HAVE(LEAF, REG, BIT, MANDATORY, HOOK) \
|
|
___X86_HAVE(LEAF, REG, BIT, MANDATORY, _X86_HOOK_##HOOK)
|
|
#define __X86_NEED(LEAF, REG, BIT, MANDATORY, HOOK) MANDATORY
|
|
#define __X86_WORD(LEAF, REG, BIT, MANDATORY, HOOK) KCPUIDS(LEAF, REG)
|
|
#define __X86_LEAF(LEAF, REG, BIT, MANDATORY, HOOK) LEAF
|
|
#define __X86_REG(LEAF, REG, BIT, MANDATORY, HOOK) REG
|
|
#define __X86_BIT(LEAF, REG, BIT, MANDATORY, HOOK) BIT
|
|
|
|
#ifndef __ASSEMBLER__
|
|
#define ___X86_HAVE(LEAF, REG, BIT, MANDATORY, HOOK) \
|
|
HOOK(!!(MANDATORY || KCPUIDS(LEAF, REG) & (1u << BIT)))
|
|
#else
|
|
#define ___X86_HAVE(LEAF, REG, BIT, MANDATORY, HOOK) \
|
|
$1 << (BIT % 8), BIT / 8 + KCPUIDS(LEAF, REG)
|
|
#endif
|
|
|
|
#define _X86_HOOK__(X) X
|
|
#define _X86_HOOK_AVX(X) \
|
|
({ \
|
|
YOINK(_init_enableavx); \
|
|
X; \
|
|
})
|
|
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
COSMOPOLITAN_C_START_
|
|
|
|
int _init_enableavx(void) pureconst;
|
|
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_X86FEATURE_H_ */
|