#!/usr/bin/awk # SPDX-License-Identifier: GPL-2.0 # # Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeatures.h # BEGIN { FS="[ \t]+"; mcount = 0; } # Generate a list of tokens matching (as opposed to separated by) a regex. function split_by_regex(str, re, fields, _rs, _rl, _n) { _rs = RSTART; _rl = RLENGTH; delete fields; _n = 0; while (match(str, re) > 0) { fields[++_n] = substr(str, RSTART, RLENGTH); str = substr(str, RSTART+RLENGTH); } RSTART = _rs; RLENGTH = _rl; return _n; } $1 == "#define" && NF >= 2 { name = $2; macro[++mcount] = name; public[name] = 0; nf = split_by_regex($0, "([#a-zA-Z0-9_]+|\\([^\\)]+\\)|\\/\\*.*\\*\\/)", f); for (i = 3; i <= nf; i++) { if (f[i] ~ /^[0-9]+$/) { val[name] = 0 + f[i]; } else if (f[i] ~ /^\([0-9 \t]+\*[0-9 \t]+\+[0-9 \t]+\)$/) { sx = f[i]; split(sx, ax, /[^0-9]+/); val[name] = ax[2]*ax[3] + ax[4]; } else if (f[i] ~ /^\/\*/ && match(f[i], /"[^"]*"/)) { tag[name] = substr(f[i], RSTART+1, RLENGTH-2); public[name] = 1; } } if (tag[name] == "" && match(name, /^([^_]+_){2}/)) { tag[name] = substr(name, RSTART+RLENGTH); } } END { tables[1] = "x86_cap_flags X86_FEATURE_ NCAPINTS"; tables[2] = "x86_bug_flags X86_BUG_ NBUGINTS"; tables[3] = "x86_vmx_flags VMX_FEATURE_ NVMXINTS"; printf "#ifndef _ASM_X86_CPUFEATURES_H\n"; printf "#include \n"; printf "#endif\n\n"; printf "#ifdef CONFIG_X86_VMX_FEATURE_NAMES\n"; printf "#ifndef _ASM_X86_VMXFEATURES_H\n"; printf "#include \n"; printf "#endif\n"; for (table in tables) { split(tables[table],t); l = length(t[2]); delete pm; words = val[t[3]]; words += words % 2; # Pad to 64 bits for (i = 0; i < words; i++) pm[i] = 0; printf "\n#ifdef %s\n\n", t[3]; printf "const char * const %s[%s*32] = {\n", t[1], t[3]; for (n = 1; n <= mcount; n++) { m = macro[n]; if (substr(m, 1, l) == t[2] && tag[m]) { v = val[m]; w = int(v/32); b = v % 32; printf "\t[%2d*32+%2d] = \"%s\",\n", w, b, tolower(tag[m]); if (public[m]) pm[w] += 2^b; } } printf "};\n"; printf "const u32 %s_export_mask[%d] = {\n", t[1], words; for (i = 0; i < words; i++) { printf "\t0x%08x,\n", pm[i]; } printf "};\n\n"; printf "#endif /* %s */\n", t[3]; } }