summaryrefslogtreecommitdiff
path: root/opcodes/i386-gen.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2022-12-22 09:32:29 +0100
committerJan Beulich <jbeulich@suse.com>2022-12-22 09:32:29 +0100
commit4d97c5c833e7d5aee97386aa1a3fe126c1261a24 (patch)
tree1ee46c31e78625b1b69ee932ecd29a6cc810714f /opcodes/i386-gen.c
parent2011a547790488fb3a8c8e8e33044b61c702339a (diff)
downloadbinutils-gdb-4d97c5c833e7d5aee97386aa1a3fe126c1261a24.tar.gz
x86: re-work ISA extension dependency handling
Getting both forward and reverse ISA dependencies right / consistent has been a permanent source of mistakes. Reduce what needs specifying manually to just the direct forward dependencies. Transitive forward dependencies as well as reverse ones are now derived and hence cannot go out of sync anymore (at least in the vast majority of cases; there are a few special cases to still take care of manually). In the course of this several CPU_ANY_*_FLAGS disappear, requiring adjustment to the assembler's cpu_arch[]. Note that to retain the correct reverse dependency of AVX512F wrt AVX512-VP2INTERSECT, the latter has the previously missing AVX512F prereq added. Note further that to avoid adding the following undue prereqs: * ATHLON, K8, and AMDFAM10 gain CMOV and FXSR, * IAMCU gains 387, auxiliary table entries (including a colon-separated modifier) are introduced in addition to the ones representing from converting the old table. To maintain forward-only dependencies between AVX (XOP) and SSE* (SSE4a) (i.e. "nosse" not disabling AVX), reverse dependency tracking is artifically suppressed. As a side effect disabling of SSE or SSE2 will now also disable AES, PCLMUL, and SHA (respective elements were missing from CPU_ANY_SSE2_FLAGS).
Diffstat (limited to 'opcodes/i386-gen.c')
-rw-r--r--opcodes/i386-gen.c797
1 files changed, 328 insertions, 469 deletions
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index ac5277e0e9d..27721c54f64 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -18,6 +18,7 @@
MA 02110-1301, USA. */
#include "sysdep.h"
+#include <stdbool.h>
#include <stdio.h>
#include <errno.h>
#include "getopt.h"
@@ -37,446 +38,192 @@
static const char *program_name = NULL;
static int debug = 0;
-typedef struct initializer
+typedef struct dependency
{
const char *name;
- const char *init;
-} initializer;
+ /* Note: Only direct dependencies should be enumerated. */
+ const char *deps;
+} dependency;
-static initializer cpu_flag_init[] =
+static const dependency isa_dependencies[] =
{
- { "CPU_UNKNOWN_FLAGS",
+ { "UNKNOWN",
"~IAMCU" },
- { "CPU_GENERIC32_FLAGS",
- "186|286|386" },
- { "CPU_GENERIC64_FLAGS",
- "CPU_PENTIUMPRO_FLAGS|Clflush|SYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|LM" },
- { "CPU_NONE_FLAGS",
- "0" },
- { "CPU_I186_FLAGS",
+ { "GENERIC32",
+ "386" },
+ { "GENERIC64",
+ "PENTIUMPRO|Clflush|SYSCALL|MMX|SSE2|LM" },
+ { "NONE",
+ "0" },
+ { "PENTIUMPRO",
+ "686|Nop" },
+ { "P2",
+ "PENTIUMPRO|MMX" },
+ { "P3",
+ "P2|SSE" },
+ { "P4",
+ "P3|Clflush|SSE2" },
+ { "NOCONA",
+ "GENERIC64|FISTTP|SSE3|CX16" },
+ { "CORE",
+ "P4|FISTTP|SSE3|CX16" },
+ { "CORE2",
+ "NOCONA|SSSE3" },
+ { "COREI7",
+ "CORE2|SSE4_2|Rdtscp" },
+ { "K6",
+ "186|286|386|486|586|SYSCALL|387|MMX" },
+ { "K6_2",
+ "K6|3dnow" },
+ { "ATHLON",
+ "K6_2|686:min|687|Nop|3dnowA" },
+ { "K8",
+ "ATHLON|Rdtscp|SSE2|LM" },
+ { "AMDFAM10",
+ "K8|FISTTP|SSE4A|ABM" },
+ { "BDVER1",
+ "GENERIC64|FISTTP|Rdtscp|CX16|XOP|ABM|LWP|SVME|AES|PCLMUL|PRFCHW" },
+ { "BDVER2",
+ "BDVER1|FMA|BMI|TBM|F16C" },
+ { "BDVER3",
+ "BDVER2|Xsaveopt|FSGSBase" },
+ { "BDVER4",
+ "BDVER3|AVX2|Movbe|BMI2|RdRnd|MWAITX" },
+ { "ZNVER1",
+ "GENERIC64|FISTTP|Rdtscp|CX16|AVX2|SSE4A|ABM|SVME|AES|PCLMUL|PRFCHW|FMA|BMI|F16C|Xsaveopt|FSGSBase|Movbe|BMI2|RdRnd|ADX|RdSeed|SMAP|SHA|XSAVEC|XSAVES|ClflushOpt|CLZERO|MWAITX" },
+ { "ZNVER2",
+ "ZNVER1|CLWB|RDPID|RDPRU|MCOMMIT|WBNOINVD" },
+ { "ZNVER3",
+ "ZNVER2|INVLPGB|TLBSYNC|VAES|VPCLMULQDQ|INVPCID|SNP|OSPKE" },
+ { "ZNVER4",
+ "ZNVER3|AVX512F|AVX512DQ|AVX512IFMA|AVX512CD|AVX512BW|AVX512VL|AVX512_BF16|AVX512VBMI|AVX512_VBMI2|AVX512_VNNI|AVX512_BITALG|AVX512_VPOPCNTDQ|GFNI|RMPQUERY" },
+ { "BTVER1",
+ "GENERIC64|FISTTP|CX16|Rdtscp|SSSE3|SSE4A|ABM|PRFCHW|CX16|Clflush|FISTTP|SVME" },
+ { "BTVER2",
+ "BTVER1|AVX|BMI|F16C|AES|PCLMUL|Movbe|Xsaveopt|PRFCHW" },
+ { "286",
"186" },
- { "CPU_I286_FLAGS",
- "CPU_I186_FLAGS|286" },
- { "CPU_I386_FLAGS",
- "CPU_I286_FLAGS|386" },
- { "CPU_I486_FLAGS",
- "CPU_I386_FLAGS|486" },
- { "CPU_I586_FLAGS",
- "CPU_I486_FLAGS|387|586" },
- { "CPU_I686_FLAGS",
- "CPU_I586_FLAGS|686|687|CMOV|FXSR" },
- { "CPU_PENTIUMPRO_FLAGS",
- "CPU_I686_FLAGS|Nop" },
- { "CPU_P2_FLAGS",
- "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
- { "CPU_P3_FLAGS",
- "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
- { "CPU_P4_FLAGS",
- "CPU_P3_FLAGS|Clflush|CPU_SSE2_FLAGS" },
- { "CPU_NOCONA_FLAGS",
- "CPU_GENERIC64_FLAGS|FISTTP|CPU_SSE3_FLAGS|CX16" },
- { "CPU_CORE_FLAGS",
- "CPU_P4_FLAGS|FISTTP|CPU_SSE3_FLAGS|CX16" },
- { "CPU_CORE2_FLAGS",
- "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
- { "CPU_COREI7_FLAGS",
- "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|Rdtscp" },
- { "CPU_K6_FLAGS",
- "186|286|386|486|586|SYSCALL|387|CPU_MMX_FLAGS" },
- { "CPU_K6_2_FLAGS",
- "CPU_K6_FLAGS|3dnow" },
- { "CPU_ATHLON_FLAGS",
- "CPU_K6_2_FLAGS|686|687|Nop|3dnowA" },
- { "CPU_K8_FLAGS",
- "CPU_ATHLON_FLAGS|Rdtscp|CPU_SSE2_FLAGS|LM" },
- { "CPU_AMDFAM10_FLAGS",
- "CPU_K8_FLAGS|FISTTP|CPU_SSE4A_FLAGS|LZCNT|POPCNT" },
- { "CPU_BDVER1_FLAGS",
- "CPU_GENERIC64_FLAGS|FISTTP|Rdtscp|CX16|CPU_XOP_FLAGS|LZCNT|POPCNT|LWP|SVME|AES|PCLMUL|PRFCHW" },
- { "CPU_BDVER2_FLAGS",
- "CPU_BDVER1_FLAGS|FMA|BMI|TBM|F16C" },
- { "CPU_BDVER3_FLAGS",
- "CPU_BDVER2_FLAGS|Xsaveopt|FSGSBase" },
- { "CPU_BDVER4_FLAGS",
- "CPU_BDVER3_FLAGS|AVX2|Movbe|BMI2|RdRnd|MWAITX" },
- { "CPU_ZNVER1_FLAGS",
- "CPU_GENERIC64_FLAGS|FISTTP|Rdtscp|CX16|CPU_AVX2_FLAGS|SSE4A|LZCNT|POPCNT|SVME|AES|PCLMUL|PRFCHW|FMA|BMI|F16C|Xsaveopt|FSGSBase|Movbe|BMI2|RdRnd|ADX|RdSeed|SMAP|SHA|XSAVEC|XSAVES|ClflushOpt|CLZERO|MWAITX" },
- { "CPU_ZNVER2_FLAGS",
- "CPU_ZNVER1_FLAGS|CLWB|RDPID|RDPRU|MCOMMIT|WBNOINVD" },
- { "CPU_ZNVER3_FLAGS",
- "CPU_ZNVER2_FLAGS|INVLPGB|TLBSYNC|VAES|VPCLMULQDQ|INVPCID|SNP|OSPKE" },
- { "CPU_ZNVER4_FLAGS",
- "CPU_ZNVER3_FLAGS|AVX512F|AVX512DQ|AVX512IFMA|AVX512CD|AVX512BW|AVX512VL|AVX512_BF16|AVX512VBMI|AVX512_VBMI2|AVX512_VNNI|AVX512_BITALG|AVX512_VPOPCNTDQ|GFNI|RMPQUERY" },
- { "CPU_BTVER1_FLAGS",
- "CPU_GENERIC64_FLAGS|FISTTP|CX16|Rdtscp|CPU_SSSE3_FLAGS|SSE4A|LZCNT|POPCNT|PRFCHW|CX16|Clflush|FISTTP|SVME" },
- { "CPU_BTVER2_FLAGS",
- "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|BMI|F16C|AES|PCLMUL|Movbe|Xsaveopt|PRFCHW" },
- { "CPU_8087_FLAGS",
- "8087" },
- { "CPU_287_FLAGS",
- "287" },
- { "CPU_387_FLAGS",
+ { "386",
+ "286" },
+ { "486",
+ "386" },
+ { "586",
+ "486|387" },
+ { "586:nofpu",
+ "486" },
+ { "686",
+ "586|687|CMOV|FXSR" },
+ { "686:min",
+ "586|687" },
+ { "687",
"387" },
- { "CPU_687_FLAGS",
- "CPU_387_FLAGS|687" },
- { "CPU_CMOV_FLAGS",
- "CMOV" },
- { "CPU_FXSR_FLAGS",
- "FXSR" },
- { "CPU_CLFLUSH_FLAGS",
- "Clflush" },
- { "CPU_NOP_FLAGS",
- "Nop" },
- { "CPU_SYSCALL_FLAGS",
- "SYSCALL" },
- { "CPU_MMX_FLAGS",
- "MMX" },
- { "CPU_SSE_FLAGS",
+ { "FISTTP",
+ "687" },
+ { "SSE2",
"SSE" },
- { "CPU_SSE2_FLAGS",
- "CPU_SSE_FLAGS|SSE2" },
- { "CPU_SSE3_FLAGS",
- "CPU_SSE2_FLAGS|SSE3" },
- { "CPU_SSSE3_FLAGS",
- "CPU_SSE3_FLAGS|SSSE3" },
- { "CPU_SSE4_1_FLAGS",
- "CPU_SSSE3_FLAGS|SSE4_1" },
- { "CPU_SSE4_2_FLAGS",
- "CPU_SSE4_1_FLAGS|SSE4_2|POPCNT" },
- { "CPU_VMX_FLAGS",
- "VMX" },
- { "CPU_SMX_FLAGS",
- "SMX" },
- { "CPU_XSAVE_FLAGS",
- "Xsave" },
- { "CPU_XSAVEOPT_FLAGS",
- "CPU_XSAVE_FLAGS|Xsaveopt" },
- { "CPU_AES_FLAGS",
- "CPU_SSE2_FLAGS|AES" },
- { "CPU_PCLMUL_FLAGS",
- "CPU_SSE2_FLAGS|PCLMUL" },
- { "CPU_FMA_FLAGS",
- "CPU_AVX_FLAGS|FMA" },
- { "CPU_FMA4_FLAGS",
- "CPU_AVX_FLAGS|FMA4" },
- { "CPU_XOP_FLAGS",
- "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|XOP" },
- { "CPU_LWP_FLAGS",
- "CPU_XSAVE_FLAGS|LWP" },
- { "CPU_BMI_FLAGS",
- "BMI" },
- { "CPU_TBM_FLAGS",
- "TBM" },
- { "CPU_MOVBE_FLAGS",
- "Movbe" },
- { "CPU_CX16_FLAGS",
- "CX16" },
- { "CPU_RDTSCP_FLAGS",
- "Rdtscp" },
- { "CPU_EPT_FLAGS",
- "EPT" },
- { "CPU_FSGSBASE_FLAGS",
- "FSGSBase" },
- { "CPU_RDRND_FLAGS",
- "RdRnd" },
- { "CPU_F16C_FLAGS",
- "CPU_AVX_FLAGS|F16C" },
- { "CPU_BMI2_FLAGS",
- "BMI2" },
- { "CPU_LZCNT_FLAGS",
- "LZCNT" },
- { "CPU_POPCNT_FLAGS",
- "POPCNT" },
- { "CPU_HLE_FLAGS",
- "HLE" },
- { "CPU_RTM_FLAGS",
- "RTM" },
- { "CPU_INVPCID_FLAGS",
- "INVPCID" },
- { "CPU_VMFUNC_FLAGS",
- "VMFUNC" },
- { "CPU_3DNOW_FLAGS",
- "CPU_MMX_FLAGS|3dnow" },
- { "CPU_3DNOWA_FLAGS",
- "CPU_3DNOW_FLAGS|3dnowA" },
- { "CPU_PADLOCK_FLAGS",
- "PadLock" },
- { "CPU_SVME_FLAGS",
- "SVME" },
- { "CPU_SSE4A_FLAGS",
- "CPU_SSE3_FLAGS|SSE4a" },
- { "CPU_ABM_FLAGS",
+ { "SSE3",
+ "SSE2" },
+ { "SSSE3",
+ "SSE3" },
+ { "SSE4_1",
+ "SSSE3" },
+ { "SSE4_2",
+ "SSE4_1|POPCNT" },
+ { "Xsaveopt",
+ "XSAVE" },
+ { "AES",
+ "SSE2" },
+ { "PCLMUL",
+ "SSE2" },
+ { "FMA",
+ "AVX" },
+ { "FMA4",
+ "AVX" },
+ { "XOP",
+ "SSE4A|FMA4" },
+ { "LWP",
+ "XSAVE" },
+ { "F16C",
+ "AVX" },
+ { "3dnow",
+ "MMX" },
+ { "3dnowA",
+ "3dnow" },
+ { "SSE4a",
+ "SSE3" },
+ { "ABM",
"LZCNT|POPCNT" },
- { "CPU_AVX_FLAGS",
- "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|AVX" },
- { "CPU_AVX2_FLAGS",
- "CPU_AVX_FLAGS|AVX2" },
- { "CPU_AVX_VNNI_FLAGS",
- "CPU_AVX2_FLAGS|AVX_VNNI" },
- { "CPU_AVX512F_FLAGS",
- "CPU_AVX2_FLAGS|AVX512F" },
- { "CPU_AVX512CD_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512CD" },
- { "CPU_AVX512ER_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512ER" },
- { "CPU_AVX512PF_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512PF" },
- { "CPU_AVX512DQ_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512DQ" },
- { "CPU_AVX512BW_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512BW" },
- { "CPU_AVX512VL_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512VL" },
- { "CPU_AVX512IFMA_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512IFMA" },
- { "CPU_AVX512VBMI_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512VBMI" },
- { "CPU_AVX512_4FMAPS_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512_4FMAPS" },
- { "CPU_AVX512_4VNNIW_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512_4VNNIW" },
- { "CPU_AVX512_VPOPCNTDQ_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512_VPOPCNTDQ" },
- { "CPU_AVX512_VBMI2_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512_VBMI2" },
- { "CPU_AVX512_VNNI_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512_VNNI" },
- { "CPU_AVX512_BITALG_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512_BITALG" },
- { "CPU_AVX512_BF16_FLAGS",
- "CPU_AVX512F_FLAGS|AVX512_BF16" },
- { "CPU_AVX512_FP16_FLAGS",
- "CPU_AVX512BW_FLAGS|AVX512_FP16" },
- { "CPU_PREFETCHI_FLAGS",
- "PREFETCHI"},
- { "CPU_AVX_IFMA_FLAGS",
- "CPU_AVX2_FLAGS|AVX_IFMA" },
- { "CPU_AVX_VNNI_INT8_FLAGS",
- "CPU_AVX2_FLAGS|AVX_VNNI_INT8" },
- { "CPU_CMPCCXADD_FLAGS",
- "CMPCCXADD" },
- { "CPU_WRMSRNS_FLAGS",
- "WRMSRNS" },
- { "CPU_MSRLIST_FLAGS",
- "MSRLIST" },
- { "CPU_AVX_NE_CONVERT_FLAGS",
- "CPU_AVX2_FLAGS|AVX_NE_CONVERT" },
- { "CPU_RAO_INT_FLAGS",
- "RAO_INT" },
- { "CPU_IAMCU_FLAGS",
- "186|286|386|486|586|IAMCU" },
- { "CPU_ADX_FLAGS",
- "ADX" },
- { "CPU_RDSEED_FLAGS",
- "RdSeed" },
- { "CPU_PRFCHW_FLAGS",
- "PRFCHW" },
- { "CPU_SMAP_FLAGS",
- "SMAP" },
- { "CPU_MPX_FLAGS",
- "CPU_XSAVE_FLAGS|MPX" },
- { "CPU_SHA_FLAGS",
- "CPU_SSE2_FLAGS|SHA" },
- { "CPU_CLFLUSHOPT_FLAGS",
- "ClflushOpt" },
- { "CPU_XSAVES_FLAGS",
- "CPU_XSAVE_FLAGS|XSAVES" },
- { "CPU_XSAVEC_FLAGS",
- "CPU_XSAVE_FLAGS|XSAVEC" },
- { "CPU_PREFETCHWT1_FLAGS",
- "PREFETCHWT1" },
- { "CPU_SE1_FLAGS",
- "SE1" },
- { "CPU_CLWB_FLAGS",
- "CLWB" },
- { "CPU_CLZERO_FLAGS",
- "CLZERO" },
- { "CPU_MWAITX_FLAGS",
- "MWAITX" },
- { "CPU_OSPKE_FLAGS",
- "CPU_XSAVE_FLAGS|OSPKE" },
- { "CPU_RDPID_FLAGS",
- "RDPID" },
- { "CPU_PTWRITE_FLAGS",
- "PTWRITE" },
- { "CPU_IBT_FLAGS",
- "IBT" },
- { "CPU_SHSTK_FLAGS",
- "SHSTK" },
- { "CPU_GFNI_FLAGS",
- "GFNI" },
- { "CPU_VAES_FLAGS",
- "VAES" },
- { "CPU_VPCLMULQDQ_FLAGS",
- "VPCLMULQDQ" },
- { "CPU_WBNOINVD_FLAGS",
- "WBNOINVD" },
- { "CPU_PCONFIG_FLAGS",
- "PCONFIG" },
- { "CPU_WAITPKG_FLAGS",
- "WAITPKG" },
- { "CPU_UINTR_FLAGS",
- "UINTR" },
- { "CPU_CLDEMOTE_FLAGS",
- "CLDEMOTE" },
- { "CPU_AMX_INT8_FLAGS",
- "CPU_AMX_TILE_FLAGS|AMX_INT8" },
- { "CPU_AMX_BF16_FLAGS",
- "CPU_AMX_TILE_FLAGS|AMX_BF16" },
- { "CPU_AMX_FP16_FLAGS",
- "CPU_AMX_TILE_FLAGS|AMX_FP16" },
- { "CPU_AMX_TILE_FLAGS",
+ { "AVX",
+ "SSE4_2|XSAVE" },
+ { "AVX2",
+ "AVX" },
+ { "AVX_VNNI",
+ "AVX2" },
+ { "AVX_IFMA",
+ "AVX2" },
+ { "AVX_VNNI_INT8",
+ "AVX2" },
+ { "AVX_NE_CONVERT",
+ "AVX2" },
+ { "AVX512F",
+ "AVX2" },
+ { "AVX512CD",
+ "AVX512F" },
+ { "AVX512ER",
+ "AVX512F" },
+ { "AVX512PF",
+ "AVX512F" },
+ { "AVX512DQ",
+ "AVX512F" },
+ { "AVX512BW",
+ "AVX512F" },
+ { "AVX512VL",
+ "AVX512F" },
+ { "AVX512IFMA",
+ "AVX512F" },
+ { "AVX512VBMI",
+ "AVX512F" },
+ { "AVX512_4FMAPS",
+ "AVX512F" },
+ { "AVX512_4VNNIW",
+ "AVX512F" },
+ { "AVX512_VPOPCNTDQ",
+ "AVX512F" },
+ { "AVX512_VBMI2",
+ "AVX512F" },
+ { "AVX512_VNNI",
+ "AVX512F" },
+ { "AVX512_BITALG",
+ "AVX512F" },
+ { "AVX512_VP2INTERSECT",
+ "AVX512F" },
+ { "AVX512_BF16",
+ "AVX512F" },
+ { "AVX512_FP16",
+ "AVX512BW" },
+ { "IAMCU",
+ "586:nofpu" },
+ { "MPX",
+ "XSAVE" },
+ { "SHA",
+ "SSE2" },
+ { "XSAVES",
+ "XSAVE" },
+ { "XSAVEC",
+ "XSAVE" },
+ { "OSPKE",
+ "XSAVE" },
+ { "AMX_INT8",
+ "AMX_TILE" },
+ { "AMX_BF16",
+ "AMX_TILE" },
+ { "AMX_FP16",
"AMX_TILE" },
- { "CPU_MOVDIRI_FLAGS",
- "MOVDIRI" },
- { "CPU_MOVDIR64B_FLAGS",
- "MOVDIR64B" },
- { "CPU_ENQCMD_FLAGS",
- "ENQCMD" },
- { "CPU_SERIALIZE_FLAGS",
- "SERIALIZE" },
- { "CPU_AVX512_VP2INTERSECT_FLAGS",
- "AVX512_VP2INTERSECT" },
- { "CPU_TDX_FLAGS",
- "TDX" },
- { "CPU_RDPRU_FLAGS",
- "RDPRU" },
- { "CPU_MCOMMIT_FLAGS",
- "MCOMMIT" },
- { "CPU_SEV_ES_FLAGS",
- "SEV_ES" },
- { "CPU_TSXLDTRK_FLAGS",
- "TSXLDTRK"},
- { "CPU_KL_FLAGS",
- "KL" },
- { "CPU_WIDEKL_FLAGS",
- "WideKL" },
- { "CPU_HRESET_FLAGS",
- "HRESET"},
- { "CPU_INVLPGB_FLAGS",
- "INVLPGB" },
- { "CPU_TLBSYNC_FLAGS",
- "TLBSYNC" },
- { "CPU_SNP_FLAGS",
- "SNP" },
- { "CPU_RMPQUERY_FLAGS",
- "RMPQUERY" },
- { "CPU_ANY_X87_FLAGS",
- "CPU_ANY_287_FLAGS|8087" },
- { "CPU_ANY_287_FLAGS",
- "CPU_ANY_387_FLAGS|287" },
- { "CPU_ANY_387_FLAGS",
- "CPU_ANY_687_FLAGS|387" },
- { "CPU_ANY_687_FLAGS",
- "687|FISTTP" },
- { "CPU_ANY_CMOV_FLAGS",
- "CMOV" },
- { "CPU_ANY_FXSR_FLAGS",
- "FXSR" },
- { "CPU_ANY_MMX_FLAGS",
- "CPU_3DNOWA_FLAGS" },
- { "CPU_ANY_SSE_FLAGS",
- "CPU_ANY_SSE2_FLAGS|SSE" },
- { "CPU_ANY_SSE2_FLAGS",
- "CPU_ANY_SSE3_FLAGS|SSE2" },
- { "CPU_ANY_SSE3_FLAGS",
- "CPU_ANY_SSSE3_FLAGS|SSE3|SSE4a" },
- { "CPU_ANY_SSSE3_FLAGS",
- "CPU_ANY_SSE4_1_FLAGS|SSSE3" },
- { "CPU_ANY_SSE4_1_FLAGS",
- "CPU_ANY_SSE4_2_FLAGS|SSE4_1" },
- { "CPU_ANY_SSE4_2_FLAGS",
- "SSE4_2" },
- { "CPU_ANY_SSE4A_FLAGS",
- "SSE4a" },
- { "CPU_ANY_AVX_FLAGS",
- "CPU_ANY_AVX2_FLAGS|F16C|FMA|FMA4|XOP|AVX" },
- { "CPU_ANY_AVX2_FLAGS",
- "CPU_ANY_AVX512F_FLAGS|AVX2|AVX_VNNI|AVX_IFMA|AVX_VNNI_INT8|AVX_NE_CONVERT" },
- { "CPU_ANY_AVX512F_FLAGS",
- "AVX512F|AVX512CD|AVX512ER|AVX512PF|AVX512DQ|CPU_ANY_AVX512BW_FLAGS|AVX512VL|AVX512IFMA|AVX512VBMI|AVX512_4FMAPS|AVX512_4VNNIW|AVX512_VPOPCNTDQ|AVX512_VBMI2|AVX512_VNNI|AVX512_BITALG|AVX512_BF16|AVX512_VP2INTERSECT" },
- { "CPU_ANY_AVX512CD_FLAGS",
- "AVX512CD" },
- { "CPU_ANY_AVX512ER_FLAGS",
- "AVX512ER" },
- { "CPU_ANY_AVX512PF_FLAGS",
- "AVX512PF" },
- { "CPU_ANY_AVX512DQ_FLAGS",
- "AVX512DQ" },
- { "CPU_ANY_AVX512BW_FLAGS",
- "AVX512BW|CPU_ANY_AVX512_FP16_FLAGS" },
- { "CPU_ANY_AVX512VL_FLAGS",
- "AVX512VL" },
- { "CPU_ANY_AVX512IFMA_FLAGS",
- "AVX512IFMA" },
- { "CPU_ANY_AVX512VBMI_FLAGS",
- "AVX512VBMI" },
- { "CPU_ANY_AVX512_4FMAPS_FLAGS",
- "AVX512_4FMAPS" },
- { "CPU_ANY_AVX512_4VNNIW_FLAGS",
- "AVX512_4VNNIW" },
- { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
- "AVX512_VPOPCNTDQ" },
- { "CPU_ANY_IBT_FLAGS",
- "IBT" },
- { "CPU_ANY_SHSTK_FLAGS",
- "SHSTK" },
- { "CPU_ANY_AVX512_VBMI2_FLAGS",
- "AVX512_VBMI2" },
- { "CPU_ANY_AVX512_VNNI_FLAGS",
- "AVX512_VNNI" },
- { "CPU_ANY_AVX512_BITALG_FLAGS",
- "AVX512_BITALG" },
- { "CPU_ANY_AVX512_BF16_FLAGS",
- "AVX512_BF16" },
- { "CPU_ANY_AMX_INT8_FLAGS",
- "AMX_INT8" },
- { "CPU_ANY_AMX_BF16_FLAGS",
- "AMX_BF16" },
- { "CPU_ANY_AMX_TILE_FLAGS",
- "AMX_TILE|AMX_INT8|AMX_BF16|AMX_FP16" },
- { "CPU_ANY_AVX_VNNI_FLAGS",
- "AVX_VNNI" },
- { "CPU_ANY_MOVDIRI_FLAGS",
- "MOVDIRI" },
- { "CPU_ANY_UINTR_FLAGS",
- "UINTR" },
- { "CPU_ANY_MOVDIR64B_FLAGS",
- "MOVDIR64B" },
- { "CPU_ANY_ENQCMD_FLAGS",
- "ENQCMD" },
- { "CPU_ANY_SERIALIZE_FLAGS",
- "SERIALIZE" },
- { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
- "AVX512_VP2INTERSECT" },
- { "CPU_ANY_TDX_FLAGS",
- "TDX" },
- { "CPU_ANY_TSXLDTRK_FLAGS",
- "TSXLDTRK" },
- { "CPU_ANY_KL_FLAGS",
- "KL|WideKL" },
- { "CPU_ANY_WIDEKL_FLAGS",
- "WideKL" },
- { "CPU_ANY_HRESET_FLAGS",
- "HRESET" },
- { "CPU_ANY_AVX512_FP16_FLAGS",
- "AVX512_FP16" },
- { "CPU_ANY_AVX_IFMA_FLAGS",
- "AVX_IFMA" },
- { "CPU_ANY_AVX_VNNI_INT8_FLAGS",
- "AVX_VNNI_INT8" },
- { "CPU_ANY_CMPCCXADD_FLAGS",
- "CMPCCXADD" },
- { "CPU_ANY_WRMSRNS_FLAGS",
- "WRMSRNS" },
- { "CPU_ANY_MSRLIST_FLAGS",
- "MSRLIST" },
- { "CPU_ANY_AVX_NE_CONVERT_FLAGS",
- "AVX_NE_CONVERT" },
- { "CPU_ANY_RAO_INT_FLAGS",
- "RAO_INT"},
};
+/* This array is populated as process_i386_initializers() walks cpu_flags[]. */
+static unsigned char isa_reverse_deps[Cpu64][Cpu64];
+
typedef struct bitfield
{
int position;
@@ -867,32 +614,6 @@ next_field (char *str, char sep, char **next, char *last)
static void set_bitfield (char *, bitfield *, int, unsigned int, int);
-static int
-set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
- int lineno)
-{
- char *str, *next, *last;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
- if (strcmp (cpu_flag_init[i].name, f) == 0)
- {
- /* Turn on selective bits. */
- char *init = xstrdup (cpu_flag_init[i].init);
- last = init + strlen (init);
- for (next = init; next && next < last; )
- {
- str = next_field (next, '|', &next, last);
- if (str)
- set_bitfield (str, array, 1, size, lineno);
- }
- free (init);
- return 0;
- }
-
- return -1;
-}
-
static void
set_bitfield (char *f, bitfield *array, int value,
unsigned int size, int lineno)
@@ -933,10 +654,6 @@ set_bitfield (char *f, bitfield *array, int value,
}
}
- /* Handle CPU_XXX_FLAGS. */
- if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
- return;
-
if (lineno != -1)
fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
else
@@ -944,6 +661,73 @@ set_bitfield (char *f, bitfield *array, int value,
}
static void
+add_isa_dependencies (bitfield *flags, const char *f, int value,
+ unsigned int reverse)
+{
+ unsigned int i;
+ char *str = NULL;
+ const char *isa = f;
+ bool is_isa = false, is_avx = false;
+
+ /* Need to find base entry for references to auxiliary ones. */
+ if (strchr (f, ':'))
+ {
+ str = xstrdup (f);
+ *strchr (str, ':') = '\0';
+ isa = str;
+ }
+ for (i = 0; i < Cpu64; ++i)
+ if (strcasecmp (flags[i].name, isa) == 0)
+ {
+ flags[i].value = value;
+ if (reverse < ARRAY_SIZE (isa_reverse_deps[0])
+ /* Don't record the feature itself here. */
+ && reverse != i
+ /* Don't record base architectures. */
+ && reverse > Cpu686)
+ isa_reverse_deps[i][reverse] = 1;
+ is_isa = true;
+ if (i == CpuAVX || i == CpuXOP)
+ is_avx = true;
+ break;
+ }
+ free (str);
+
+ /* Do not turn off dependencies. */
+ if (is_isa && !value)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE (isa_dependencies); ++i)
+ if (strcasecmp (isa_dependencies[i].name, f) == 0)
+ {
+ char *deps = xstrdup (isa_dependencies[i].deps);
+ char *next = deps;
+ char *last = deps + strlen (deps);
+
+ for (; next && next < last; )
+ {
+ char *str = next_field (next, '|', &next, last);
+
+ /* No AVX/XOP -> SSE reverse dependencies. */
+ if (is_avx && strncmp (str, "SSE", 3) == 0)
+ add_isa_dependencies (flags, str, value, CpuMax);
+ else
+ add_isa_dependencies (flags, str, value, reverse);
+ }
+ free (deps);
+
+ /* ISA extensions with dependencies need CPU_ANY_*_FLAGS emitted. */
+ if (reverse < ARRAY_SIZE (isa_reverse_deps[0]))
+ isa_reverse_deps[reverse][reverse] = 1;
+
+ return;
+ }
+
+ if (!is_isa)
+ fail (_("unknown bitfield: %s\n"), f);
+}
+
+static void
output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
int macro, const char *comma, const char *indent)
{
@@ -975,18 +759,27 @@ output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
}
static void
-process_i386_cpu_flag (FILE *table, char *flag, int macro,
+process_i386_cpu_flag (FILE *table, char *flag,
+ const char *name,
const char *comma, const char *indent,
- int lineno)
+ int lineno, unsigned int reverse)
{
char *str, *next = flag, *last;
unsigned int i;
int value = 1;
+ bool is_isa = false;
bitfield flags [ARRAY_SIZE (cpu_flags)];
/* Copy the default cpu flags. */
memcpy (flags, cpu_flags, sizeof (cpu_flags));
+ if (flag == NULL)
+ {
+ for (i = 0; i < ARRAY_SIZE (isa_reverse_deps[0]); ++i)
+ flags[i].value = isa_reverse_deps[reverse][i];
+ goto output;
+ }
+
if (flag[0] == '~')
{
last = flag + strlen (flag);
@@ -1013,19 +806,54 @@ process_i386_cpu_flag (FILE *table, char *flag, int macro,
value = 0;
}
+ if (name != NULL && value != 0)
+ {
+ for (i = 0; i < ARRAY_SIZE (flags); i++)
+ if (strcasecmp (flags[i].name, name) == 0)
+ {
+ add_isa_dependencies (flags, name, 1, reverse);
+ is_isa = true;
+ break;
+ }
+ }
+
if (strcmp (flag, "0"))
{
+ if (is_isa)
+ return;
+
/* Turn on/off selective bits. */
last = flag + strlen (flag);
for (; next && next < last; )
{
str = next_field (next, '|', &next, last);
- if (str)
+ if (name == NULL)
set_bitfield (str, flags, value, ARRAY_SIZE (flags), lineno);
+ else
+ add_isa_dependencies (flags, str, value, reverse);
}
}
- output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
+ output:
+ if (name != NULL)
+ {
+ size_t len = strlen (name);
+ char *upper = xmalloc (len + 1);
+
+ for (i = 0; i < len; ++i)
+ {
+ /* Don't emit #define-s for auxiliary entries. */
+ if (name[i] == ':')
+ return;
+ upper[i] = TOUPPER (name[i]);
+ }
+ upper[i] = '\0';
+ fprintf (table, "\n#define CPU_%s%s_FLAGS \\\n",
+ flag != NULL ? "": "ANY_", upper);
+ free (upper);
+ }
+
+ output_cpu_flags (table, flags, ARRAY_SIZE (flags), name != NULL,
comma, indent);
}
@@ -1396,7 +1224,7 @@ output_i386_opcode (FILE *table, const char *name, char *str,
process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
operand_types, lineno);
- process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
+ process_i386_cpu_flag (table, cpu_flags, NULL, ",", " ", lineno, CpuMax);
fprintf (table, " { ");
@@ -1935,7 +1763,6 @@ process_i386_initializers (void)
{
unsigned int i;
FILE *fp = fopen ("i386-init.h", "w");
- char *init;
if (fp == NULL)
fail (_("can't create i386-init.h, errno = %s\n"),
@@ -1943,12 +1770,44 @@ process_i386_initializers (void)
process_copyright (fp);
- for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
+ for (i = 0; i < Cpu64; i++)
+ process_i386_cpu_flag (fp, "0", cpu_flags[i].name, "", " ", -1, i);
+
+ for (i = 0; i < ARRAY_SIZE (isa_dependencies); i++)
+ {
+ char *deps = xstrdup (isa_dependencies[i].deps);
+
+ process_i386_cpu_flag (fp, deps, isa_dependencies[i].name,
+ "", " ", -1, CpuMax);
+ free (deps);
+ }
+
+ /* Early x87 is somewhat special: Both 287 and 387 not only add new insns
+ but also remove some. Hence 8087 isn't a prereq to 287, and 287 isn't
+ one to 387. We want the reverse to be true though: Disabling 8087 also
+ is to disable 287+ and later; disabling 287 also means disabling 387+. */
+ memcpy (isa_reverse_deps[Cpu287], isa_reverse_deps[Cpu387],
+ sizeof (isa_reverse_deps[0]));
+ isa_reverse_deps[Cpu287][Cpu387] = 1;
+ memcpy (isa_reverse_deps[Cpu8087], isa_reverse_deps[Cpu287],
+ sizeof (isa_reverse_deps[0]));
+ isa_reverse_deps[Cpu8087][Cpu287] = 1;
+
+ /* While we treat POPCNT as a prereq to SSE4.2, its disabling should not
+ lead to disabling of anything else. */
+ memset (isa_reverse_deps[CpuPOPCNT], 0, sizeof (isa_reverse_deps[0]));
+
+ for (i = Cpu686 + 1; i < ARRAY_SIZE (isa_reverse_deps); i++)
{
- fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
- init = xstrdup (cpu_flag_init[i].init);
- process_i386_cpu_flag (fp, init, 1, "", " ", -1);
- free (init);
+ size_t len;
+ char *upper;
+
+ if (memchr(isa_reverse_deps[i], 1,
+ ARRAY_SIZE (isa_reverse_deps[0])) == NULL)
+ continue;
+
+ isa_reverse_deps[i][i] = 1;
+ process_i386_cpu_flag (fp, NULL, cpu_flags[i].name, "", " ", -1, i);
}
fprintf (fp, "\n");