Как проверить, требует ли двоичный файл SSE4 или AVX в Linux

11954
user2284570

В Linux /proc/cpuinfoпозволяет проверять все флаги процессора, которые есть у машины, простым способом.
Обычно, если программе требуется расширенный набор команд машины, самый простой способ определить это - запустить ее и посмотреть, вызывает ли она SIGILLсигнал.

Но в моем случае все мои процессоры поддерживают как минимум SSE4.1 и AVX.
Итак, есть ли простой способ проверить, есть ли внутри двоичного файла специальные инструкции?

15
Может быть, есть эмуляторы, которые позволяют выбрать, какие наборы инструкций включены. QEMU в настоящее время не поддерживает AVX, поэтому он может «работать не так, как ожидалось»: http://superuser.com/questions/453786/how-do-i-get-avx-support-in-qemu || http://superuser.com/questions/548740/disabling-instruction-set-in-virtualbox Ciro Santilli 新疆改造中心 六四事件 法轮功 8 лет назад 0
`objdump --disassemble` выполняет разборку. Вы можете использовать `objdump` для генерации списка мнемоник. Он является частью Binutils, поэтому он доступен в системах GNU Linux. Кроме того, дополнительные инструкции могут присутствовать, но не могут быть выполнены. У программы могли быть охранники времени выполнения. jww 7 лет назад 2
@jww: heemm, да, но я беспокоюсь о том, чтобы исполняемый файл работал везде, а не о том, чтобы изучать более 600 кодов операций для программирования на ассемблере. user2284570 7 лет назад 0
Ну, ты вроде должен узнать, что ты можешь (и не можешь) использовать. Это ваша ответственность. Я полагаю, вы могли бы скомпилировать с помощью `-mavx`, чтобы компилятор выбирал только из AVX ISA, но есть способы обойти его. Например, встроенный ассемблер обычно может обойти проверки ISA компилятора. jww 7 лет назад 0
@jww: а если бинарный файл является закрытым исходным кодом * (в смысле исходный код удаляется после сборки) * общий объект строится с помощью проприетарного скрипта / компилятора? user2284570 7 лет назад 0
все ответы ниже делают что-то вроде разборки. Помните, что сам код может иметь защиту (как упомянуто @jww), то есть он определяет набор команд, поддерживаемых процессором, и использует самую быструю подпрограмму, которая будет работать на процессоре, но objdump будет по-прежнему включать инструкции SSE4 / AVX. Короче говоря: наличие этих кодов операций не обязательно означает, что они используются. OTOH, если их нет, вы можете быть уверены, что совместимость с SSE4 / AVX не будет проблемой. Ro-ee 7 лет назад 0
@ Ro-ee: в моем случае только аргументы компилятора командной строки. Поэтому, если они присутствуют, они будут загружены в процессор. user2284570 7 лет назад 0
[какие инструкции используют двоичные файлы x86-64?] (https://unix.stackexchange.com/q/249380/44425), [Как проверить, использует ли скомпилированный код инструкции sse и avx?] (https: // stackoverflow. ком / кв / 47878352 / +995714) phuclv 6 лет назад 0

4 ответа на вопрос

16
Kyselejsyreček

Я столкнулся с той же проблемой, когда пытался понять процессы оптимизации GCC и выяснить, какие инструкции использовались или не использовались во время этого процесса. Так как я не дружу с огромным количеством кодов операций, я искал способ визуализации конкретных (скажем, SSE3) инструкций в разобранном коде или, по крайней мере, для вывода некоторой минимальной статистики, например, есть ли и сколько таких инструкций. в двоичном

Я не нашел никакого существующего решения, но ответ Джонатана Бен-Авраама оказался очень полезным, поскольку он указывает на отличный (и даже частично структурированный) источник кодов операций. Основываясь на этих данных, я написал скрипт Bash, который может визуализировать определенные наборы команд или распечатывать статистику о них, используя grepпри выводе из objdump.

Список кодов операций был преобразован в автономный скрипт Bash, который затем включается (в целях лучшей читаемости) в основной файл, который я назвал просто opcode. Поскольку коды операций в gas.vim( определения синтаксиса Ширкаvim, из ответа Джонатана) систематически (на первый взгляд) группировались в соответствии с различными архитектурами ЦП, я попытался сохранить это разделение и сделать отображение набора архитектур-> инструкций ; Сейчас я не уверен, что это хорошая идея. Отображение не является точным, и мне даже пришлось внести некоторые изменения в оригиналеgas.vimгруппировка. Поскольку связанные с архитектурой наборы инструкций не были моей первоначальной целью, я пытался создавать только наборы инструкций основных архитектур, описанных в Интернете, но не обращаясь к документации производителей. Архитектура AMD мне не кажется надежной (за исключением наборов инструкций, таких как 3DNow! И SSE5). Тем не менее, я решил оставить здесь код для наборов инструкций различных архитектур, чтобы кто-то еще мог исследовать, исправлять / улучшать и давать другим некоторые предварительные результаты.

Начало основного файла с именем opcode:

#!/bin/bash # # Searches disassembled code for specific instructions. # # Opcodes obtained from: https://github.com/Shirk/vim-gas/blob/master/syntax/gas.vim # # List of opcodes has been obtained using the following commands and making a few modifications: # echo '#!/bin/bash' > Opcode_list # wget -q -O- https://raw.githubusercontent.com/Shirk/vim-gas/master/syntax/gas.vim \ # | grep -B1 -E 'syn keyword gasOpcode_|syn match gasOpcode' | \ # sed -e '/^--$/d' -e 's/"-- Section:/\n#/g' \ # -e 's/syn keyword gasOpcode_\([^\t]*\)*\(\t\)*\(.*\)/Opcode_\1="\$ \3"/g' \ # -e 's/Opcode_PENT_3DNOW/Opcode_ATHLON_3DNOW/g' -e 's/\\//g' \ # -e 's/syn match gasOpcode_\([^\t]*\)*.*\/<\(.*\)>\//Opcode_\1="\$ \2"/g' \ # >> Opcode_list # # Modify file Opcode_list replacing all occurrences of: # * Opcode_Base within the section "Tejas New Instructions (SSSE3)" with Opcode_SSSE3 # * Opcode_Base within the section "Willamette MMX instructions (SSE2 SIMD Integer Instructions)" # with Opcode_WILLAMETTE_Base  # return values EXIT_FOUND=0 EXIT_NOT_FOUND=1 EXIT_USAGE=2  # settings InstSet_Base="" Recursive=false Count_Matching=false Leading_Separator='\s' Trailing_Separator='(\s|$)' # $ matches end of line for non-parametric instructions like nop Case_Insensitive=false Invert=false Verbose=false Stop_After=0 Line_Numbers=false Leading_Context=0 Trailing_Context=0  source Opcode_list # include opcodes from a separate file  # GAS-specific opcodes (unofficial names) belonging to the x64 instruction set. # They are generated by GNU tools (e.g. GDB, objdump) and specify a variant of ordinal opcodes like NOP and MOV. # If you do not want these opcodes to be recognized by this script, comment out the following line. Opcode_X64_GAS="nopw nopl movabs"   # instruction sets InstSet_X86="8086_Base 186_Base 286_Base 386_Base 486_Base PENT_Base P6_Base KATMAI_Base WILLAMETTE_Base PENTM_Base" InstSet_IA64="IA64_Base" InstSet_X64="PRESCOTT_Base X64_Base X86_64_Base NEHALEM_Base X64_GAS" InstSet_MMX="PENT_MMX KATMAI_MMX X64_MMX" InstSet_MMX2="KATMAI_MMX2" InstSet_3DNOW="ATHLON_3DNOW" InstSet_SSE="KATMAI_SSE P6_SSE X64_SSE" InstSet_SSE2="SSE2 X64_SSE2" InstSet_SSE3="PRESCOTT_SSE3" InstSet_SSSE3="SSSE3" InstSet_VMX="VMX X64_VMX" InstSet_SSE4_1="SSE41 X64_SSE41" InstSet_SSE4_2="SSE42 X64_SSE42" InstSet_SSE4A="AMD_SSE4A" InstSet_SSE5="AMD_SSE5" InstSet_FMA="FUTURE_FMA" InstSet_AVX="SANDYBRIDGE_AVX"  InstSetDep_X64="X86" InstSetDep_MMX2="MMX" InstSetDep_SSE2="SSE" InstSetDep_SSE3="SSE2" InstSetDep_SSSE3="SSE3" InstSetDep_SSE4_1="SSSE3" InstSetDep_SSE4_2="SSE4_1" InstSetDep_SSE4A="SSE3" InstSetDep_SSE5="FMA AVX" # FIXME not reliable  InstSetList="X86 IA64 X64 MMX MMX2 3DNOW SSE SSE2 SSE3 SSSE3 VMX SSE4_1 SSE4_2 SSE4A SSE5 FMA AVX"   # architectures Arch_8086="8086_Base" Arch_186="186_Base" Arch_286="286_Base" Arch_386="386_Base" Arch_486="486_Base" Arch_Pentium="PENT_Base PENT_MMX" # Pentium = P5 architecture Arch_Athlon="ATHLON_3DNOW" Arch_Deschutes="P6_Base P6_SSE" # Pentium II Arch_Katmai="KATMAI_Base KATMAI_MMX KATMAI_MMX2 KATMAI_SSE" # Pentium III Arch_Willamette="WILLAMETTE_Base SSE2" # original Pentium IV (x86) Arch_PentiumM="PENTM_Base" Arch_Prescott="PRESCOTT_Base X64_Base X86_64_Base X64_SSE2 PRESCOTT_SSE3 VMX X64_VMX X64_GAS" # later Pentium IV (x64) with SSE3 (Willamette only implemented SSE2 instructions) and VT (VT-x, aka VMX) Arch_P6="" Arch_Barcelona="ATHLON_3DNOW AMD_SSE4A" Arch_IA64="IA64_Base" # 64-bit Itanium RISC processor; incompatible with x64 architecture Arch_Penryn="SSSE3 SSE41 X64_SSE41" # later (45nm) Core 2 with SSE4.1 Arch_Nehalem="NEHALEM_Base SSE42 X64_SSE42" # Core i# Arch_SandyBridge="SANDYBRIDGE_AVX" Arch_Haswell="FUTURE_FMA" Arch_Bulldozer="AMD_SSE5"  ArchDep_8086="" ArchDep_186="8086" ArchDep_286="186" ArchDep_386="286" ArchDep_486="386" ArchDep_Pentium="486" ArchDep_Athlon="Pentium" # FIXME not reliable ArchDep_Deschutes="Pentium" ArchDep_Katmai="Deschutes" ArchDep_Willamette="Katmai" ArchDep_PentiumM="Willamette" # FIXME Pentium M is a Pentium III modification (with SSE2). Does it support also WILLAMETTE_Base instructions? ArchDep_Prescott="Willamette" ArchDep_P6="Prescott" # P6 started with Pentium Pro; FIXME Pentium Pro did not support MMX instructions (introduced again in Pentium II aka Deschutes) ArchDep_Barcelona="Prescott" # FIXME not reliable ArchDep_IA64="" ArchDep_Penryn="P6" ArchDep_Nehalem="Penryn" ArchDep_SandyBridge="Nehalem" ArchDep_Haswell="SandyBridge" ArchDep_Bulldozer="Haswell" # FIXME not reliable  ArchList="8086 186 286 386 486 Pentium Athlon Deschutes Katmai Willamette PentiumM Prescott P6 Barcelona IA64 Penryn Nehalem SandyBridge Haswell Bulldozer" 

Пример Opcode_listфайла, созданного и измененного с использованием инструкций по opcodeсостоянию на 27 октября 2014 г., можно найти по адресу http://pastebin.com/yx4rCxqs . Вы можете вставить этот файл прямо на opcodeместо source Opcode_listстроки. Я выпустил этот код, потому что Stack Exchange не позволил бы мне отправить такой большой ответ.

Наконец, остальная часть opcodeфайла с реальной логикой:

usage() { echo "Usage: $0 OPTIONS" echo "" echo " -r set instruction sets recursively according to dependency tree (must precede -a or -s)" echo " -a set architecture" echo " -s set instruction set" echo " -L show list of available architectures" echo " -l show list of available instruction sets" echo " -i show base instruction sets of current instruction set (requires -a and/or -s)" echo " -I show instructions in current instruction set (requires -a and/or -s)" echo " -c print number of matching instructions instead of normal output" echo " -f find instruction set of the following instruction (regex allowed)" echo " -d set leading opcode separator (default '$Leading_Separator')" echo " -D set trailing opcode separator (default '$Trailing_Separator')" echo " -C case-insensitive" echo " -v invert the sense of matching" echo " -V print all lines, not just the highlighted" echo " -m stop searching after n matched instructions" echo " -n print line numbers within the original input" echo " -B print n instructions of leading context" echo " -A print n instructions of trailing context" echo " -h print this help" echo echo "Multiple architectures and instruction sets can be used." echo echo "Typical usage is:" echo " objdump -M intel -d FILE | $0 OPTIONS" echo " objdump -M intel -d FILE | $0 -s SSE2 -s SSE3 -V Highlight SSE2 and SSE3 within FILE." echo " objdump -M intel -d FILE | tail -n +8 | $0 -r -a Haswell -v -m 1 Find first unknown instruction." echo " $0 -C -f ADDSD Find which instruction set an opcode belongs to." echo " $0 -f .*fma.* Find all matching instructions and their instruction sets." echo echo "The script uses Intel opcode syntax. When used in conjunction with objdump, \`-M intel' must be set in order to prevent opcode translation using AT&T syntax." echo echo "BE AWARE THAT THE LIST OF KNOWN INSTRUCTIONS OR INSTRUCTIONS SUPPORTED BY PARTICULAR ARCHITECTURES (ESPECIALLY AMD'S) IS ONLY TENTATIVE AND MAY CONTAIN MISTAKES!" kill -TRAP $TOP_PID }  list_contains() { # Returns 0 if $2 is in array $1, 1 otherwise. local e for e in $1; do [ "$e" = "$2" ] && return 0 done return 1 }  build_instruction_set() { # $1 = enum { Arch, InstSet }, $2 = architecture or instruction set as obtained using -L or -l, $3 = "architecture"/"instruction set" to be used in error message local e list_contains "`eval echo \\\$$List`" "$2" || (echo "$2 is not a valid $3."; usage) # Test if the architecture/instruction set is valid. if [ -n "`eval echo \\\$$_$`" ]; then # Add the instruction set(s) if any. for e in `eval echo \\\$$_$`; do # Skip duplicates. list_contains "$InstSet_Base" $e || InstSet_Base="$e $InstSet_Base" done fi if [ $Recursive = true ]; then for a in `eval echo \\\$$Dep_$2`; do build_instruction_set $1 $a "$3" done fi InstSet_Base="`echo $InstSet_Base | sed 's/$ *//'`" # Remove trailing space. }  trap "exit $EXIT_USAGE" TRAP # Allow usage() function to abort script execution. export TOP_PID=$$ # PID of executing process.  # Parse command line arguments. while getopts ":ra:s:LliIcf:Fd:D:CvVm:nB:A:h" o; do case $o in r) Recursive=true ;; a) build_instruction_set Arch "$OPTARG" "architecture" ;; s) build_instruction_set InstSet "$OPTARG" "instruction set" ;; L) echo $ArchList; exit $EXIT_USAGE ;; l) echo $InstSetList; exit $EXIT_USAGE ;; i) if [ -n "$InstSet_Base" ]; then echo $InstSet_Base exit $EXIT_USAGE else echo -e "No instruction set or architecture set.\n" usage fi ;; I) if [ -n "$InstSet_Base" ]; then for s in $InstSet_Base; do echo -ne "\e[31;1m$s:\e[0m " eval echo "\$Opcode_$s" done exit $EXIT_USAGE else echo -e "No instruction set or architecture set.\n" usage fi ;; c) Count_Matching=true ;; f) # Unlike architectures, instruction sets are disjoint. Found=false for s in $InstSetList; do for b in `eval echo \\\$InstSet_$s`; do Found_In_Base=false for i in `eval echo \\\$Opcode_$b`; do if [[ "$i" =~ ^$OPTARG$ ]]; then $Found_In_Base || echo -ne "Instruction set \e[33;1m$s\e[0m (base instruction set \e[32;1m$b\e[0m):" echo -ne " \e[31;1m$i\e[0m" Found_In_Base=true Found=true fi done $Found_In_Base && echo "" done done if [ $Found = false ]; then echo -e "Operation code \e[31;1m$OPTARG\e[0m has not been found in the database of known instructions." \ "Perhaps it is translated using other than Intel syntax. If obtained from objdump, check if the \`-M intel' flag is set." \ "Be aware that the search is case sensitive by default (you may use the -C flag, otherwise only lower case opcodes are accepted)." exit $EXIT_NOT_FOUND else exit $EXIT_FOUND fi ;; d) Leading_Separator="$OPTARG" ;; D) Trailing_Separator="$OPTARG" ;; C) Case_Insensitive=true ;; v) Invert=true ;; V) Verbose=true ;; m) Stop_After=$OPTARG ;; n) Line_Numbers=true ;; B) Leading_Context=$OPTARG ;; A) Trailing_Context=$OPTARG ;; h) usage ;; \?) echo -e "Unknown option: -$OPTARG\n" usage ;; esac done shift $((OPTIND-1)) [ -n "$1" ] && echo -e "Unknown command line parameter: $1\n" && usage [ -z "$InstSet_Base" ] && usage  # Create list of grep parameters. Grep_Params="--color=auto -B $Leading_Context -A $Trailing_Context" [ $Count_Matching = true ] && Grep_Params="$Grep_Params -c" [ $Case_Insensitive = true ] && Grep_Params="$Grep_Params -i" [ $Invert = true ] && Grep_Params="$Grep_Params -v" [ $Stop_After -gt 0 ] && Grep_Params="$Grep_Params -m $Stop_After" [ $Line_Numbers = true ] && Grep_Params="$Grep_Params -n"  # Build regular expression for use in grep. RegEx="" for s in $InstSet_Base; do eval RegEx=\"$RegEx \$Opcode_$s\" done # Add leading and trailing opcode separators to prevent false positives. RegEx="$Leading_Separator`echo $RegEx | sed "s/ /$(echo "$Trailing_Separator"|sed 's/[\/&]/\\\&/g')|$(echo "$Leading_Separator"|sed 's/[\/&]/\\\&/g')/g"`$Trailing_Separator"  [ $Verbose = true -a $Count_Matching = false ] && RegEx="$RegEx|\$"  # The actual search. grep $Grep_Params -E "$RegEx" && exit $EXIT_FOUND || exit $EXIT_NOT_FOUND 

Имейте в виду, что если ваш поисковый запрос слишком велик (например, с набором команд Haswell и -rпереключателем - это включает в себя сотни инструкций), вычисления могут выполняться медленно и занимать много времени на больших входных данных, для которых этот простой сценарий не был предназначен ,

За подробной информацией по использованию обращайтесь

./opcode -h 

Весь opcodeсценарий (с включенным Opcode_list) можно найти по адресу http://pastebin.com/A8bAuHAP .

Не стесняйтесь улучшать инструмент и исправлять любые ошибки, которые я мог сделать. Наконец, я хотел бы поблагодарить Джонатана Бен-Авраама за его прекрасную идею использования gas.vimфайла Ширка .

РЕДАКТИРОВАТЬ: теперь скрипт может найти, к какому набору инструкций относится код операции (можно использовать регулярное выражение).

8
Peter

Я выбил программу на Rust, которая пытается это сделать. Я думаю, что это работает, хотя это недокументировано и ужасно хрупко:

https://github.com/pkgw/elfx86exts

Пример использования:

$ cd elfx86exts $ cargo build [things happen] $ cargo run -- /bin/ls Compiling elfx86exts v0.1.0 (file:///home/peter/sw/elfx86exts) Finished dev [unoptimized + debuginfo] target(s) in 1.9 secs Running `target/debug/elfx86exts /bin/ls` MODE64 CMOV SSE2 SSE1 
Я попытался запустить его на libtensorflow.so (sha224: 8f665acf0f455d5056014dfa2d48c22ab6cf83eb073842e8304878d0) из [этого] (https://www.archlinux.org/packages/community/x86_64/tensorflow-opt-cuda/-5) (пакета ) и это заморозило весь мой компьютер. Philippe 6 лет назад 0
@Philippe Пожалуйста, отправьте вопрос на GitHub! Я думаю, что это лучшее место для обсуждения таких тем. Peter 6 лет назад 0
Хорошо, я создал проблему на вашем github. Philippe 6 лет назад 0
6
Jonathan Ben-Avraham

К сожалению, на данный момент не существует какой-либо известной утилиты, которая бы определяла требуемый набор инструкций из данного исполняемого файла.

Лучшее, что я могу предложить для x86, - это использовать objdump -dв двоичном файле ELF разбор исполняемых разделов на язык Gnu Assemply ( gas). Затем используйте определения синтаксиса Ширка,vim чтобы либо grepпросмотреть файл кода сборки, либо визуально отсканировать код ассемблера на наличие каких- gasOpcode_SSE41либо gasOpcode_SANDYBRIDGE_AVXинструкций или инструкций, которые вы видите в gas.vimфайле Ширка .

Файл на языке ассемблера содержит инструкции машинного уровня («коды операций»), которые компилятор сгенерировал при компиляции программы. Если программа была скомпилирована с флагами времени компиляции для инструкций SSE или AVX, и компилятор выпустил какие-либо инструкции SSE или AVX, то вы должны увидеть один или несколько кодов операций SSE или AVX в списке разборки, созданном objdump -d.

Например, если вы делаете grep vroundsdbв файле кода сборки и находите совпадение, то вы знаете, что для выполнения двоичного файла требуются возможности AVX.

Как видно из gas.vimфайла Ширка, для x86 существует довольно много специфичных для суб-архитектуры инструкций, поэтому grepпинг для всех кодов операций для каждой суб-архитектуры, по общему признанию, был бы утомительным. Написание программ на C, Perl или Python для этого может быть отличной идеей для проекта с открытым исходным кодом, особенно если вы найдете кого-то, кто расширит его для ARM, PPC и других архитектур.

Какова цель газа: я не мог найти, что это за программа? user2284570 10 лет назад 0
@ user2284570: я отредактировал ответ, чтобы отразить твой комментарий. НТН. Jonathan Ben-Avraham 10 лет назад 0
Sse4.2 + AVX + 3DNOW представляют сотни инструкций. Потребовалось бы много времени, чтобы начать поиск каждого из них ... user2284570 10 лет назад 0
@ user2284570: Да, я упоминал об этом. Если вам нужно делать это регулярно, было бы лучше написать скрипт на Perl, основанный на `gas.vim` Ширка. OTOH, если это проблема с одним выстрелом, то вы можете легко узнать шаблоны кодов операций, которые различают суб-архитектуры. Jonathan Ben-Avraham 10 лет назад 0
Я думаю, что библиотека для работы с кодами операций была бы чем-то отличным для начала ... user2284570 10 лет назад 0
6
Ohne Kleidung

Сначала декомпилируйте ваш бинарный файл:

objdump -d binary > binary.asm 

Затем найдите все инструкции SSE4 в файле сборки:

gawk '/\<(mpsadbw|phminposuw|pmulld|pmuldq|dpps|dppd|blendps|blendpd|blendvps|blendvpd|pblendvb|pblenddw|pminsb|pmaxsb|pminuw|pmaxuw|pminud|pmaxud|pminsd|pmaxsd|roundps|roundss|roundpd|roundsd|insertps|pinsrb|pinsrd|pinsrq|extractps|pextrb|pextrd|pextrw|pextrq|pmovsxbw|pmovzxbw|pmovsxbd|pmovzxbd|pmovsxbq|pmovzxbq|pmovsxwd|pmovzxwd|pmovsxwq|pmovzxwq|pmovsxdq|pmovzxdq|ptest|pcmpeqq|pcmpgtq|packusdw|pcmpestri|pcmpestrm|pcmpistri|pcmpistrm|crc32|popcnt|movntdqa|extrq|insertq|movntsd|movntss|lzcnt)\>/' binary.asm 

(Примечание: CRC32 может совпадать с комментариями.)

Найдите наиболее распространенные инструкции AVX (включая семейство AVX2 и AVX-512 и некоторые FMA, например vfmadd213pd):

gawk '/\<(vmovapd|vmulpd|vaddpd|vsubpd|vfmadd213pd|vfmadd231pd|vfmadd132pd|vmulsd|vaddsd|vmosd|vsubsd|vbroadcastss|vbroadcastsd|vblendpd|vshufpd|vroundpd|vroundsd|vxorpd|vfnmadd231pd|vfnmadd213pd|vfnmadd132pd|vandpd|vmaxpd|vmovmskpd|vcmppd|vpaddd|vbroadcastf128|vinsertf128|vextractf128|vfmsub231pd|vfmsub132pd|vfmsub213pd|vmaskmovps|vmaskmovpd|vpermilps|vpermilpd|vperm2f128|vzeroall|vzeroupper|vpbroadcastb|vpbroadcastw|vpbroadcastd|vpbroadcastq|vbroadcasti128|vinserti128|vextracti128|vpminud|vpmuludq|vgatherdpd|vgatherqpd|vgatherdps|vgatherqps|vpgatherdd|vpgatherdq|vpgatherqd|vpgatherqq|vpmaskmovd|vpmaskmovq|vpermps|vpermd|vpermpd|vpermq|vperm2i128|vpblendd|vpsllvd|vpsllvq|vpsrlvd|vpsrlvq|vpsravd|vblendmpd|vblendmps|vpblendmd|vpblendmq|vpblendmb|vpblendmw|vpcmpd|vpcmpud|vpcmpq|vpcmpuq|vpcmpb|vpcmpub|vpcmpw|vpcmpuw|vptestmd|vptestmq|vptestnmd|vptestnmq|vptestmb|vptestmw|vptestnmb|vptestnmw|vcompresspd|vcompressps|vpcompressd|vpcompressq|vexpandpd|vexpandps|vpexpandd|vpexpandq|vpermb|vpermw|vpermt2b|vpermt2w|vpermi2pd|vpermi2ps|vpermi2d|vpermi2q|vpermi2b|vpermi2w|vpermt2ps|vpermt2pd|vpermt2d|vpermt2q|vshuff32x4|vshuff64x2|vshuffi32x4|vshuffi64x2|vpmultishiftqb|vpternlogd|vpternlogq|vpmovqd|vpmovsqd|vpmovusqd|vpmovqw|vpmovsqw|vpmovusqw|vpmovqb|vpmovsqb|vpmovusqb|vpmovdw|vpmovsdw|vpmovusdw|vpmovdb|vpmovsdb|vpmovusdb|vpmovwb|vpmovswb|vpmovuswb|vcvtps2udq|vcvtpd2udq|vcvttps2udq|vcvttpd2udq|vcvtss2usi|vcvtsd2usi|vcvttss2usi|vcvttsd2usi|vcvtps2qq|vcvtpd2qq|vcvtps2uqq|vcvtpd2uqq|vcvttps2qq|vcvttpd2qq|vcvttps2uqq|vcvttpd2uqq|vcvtudq2ps|vcvtudq2pd|vcvtusi2ps|vcvtusi2pd|vcvtusi2sd|vcvtusi2ss|vcvtuqq2ps|vcvtuqq2pd|vcvtqq2pd|vcvtqq2ps|vgetexppd|vgetexpps|vgetexpsd|vgetexpss|vgetmantpd|vgetmantps|vgetmantsd|vgetmantss|vfixupimmpd|vfixupimmps|vfixupimmsd|vfixupimmss|vrcp14pd|vrcp14ps|vrcp14sd|vrcp14ss|vrndscaleps|vrndscalepd|vrndscaless|vrndscalesd|vrsqrt14pd|vrsqrt14ps|vrsqrt14sd|vrsqrt14ss|vscalefps|vscalefpd|vscalefss|vscalefsd|valignd|valignq|vdbpsadbw|vpabsq|vpmaxsq|vpmaxuq|vpminsq|vpminuq|vprold|vprolvd|vprolq|vprolvq|vprord|vprorvd|vprorq|vprorvq|vpscatterdd|vpscatterdq|vpscatterqd|vpscatterqq|vscatterdps|vscatterdpd|vscatterqps|vscatterqpd|vpconflictd|vpconflictq|vplzcntd|vplzcntq|vpbroadcastmb2q|vpbroadcastmw2d|vexp2pd|vexp2ps|vrcp28pd|vrcp28ps|vrcp28sd|vrcp28ss|vrsqrt28pd|vrsqrt28ps|vrsqrt28sd|vrsqrt28ss|vgatherpf0dps|vgatherpf0qps|vgatherpf0dpd|vgatherpf0qpd|vgatherpf1dps|vgatherpf1qps|vgatherpf1dpd|vgatherpf1qpd|vscatterpf0dps|vscatterpf0qps|vscatterpf0dpd|vscatterpf0qpd|vscatterpf1dps|vscatterpf1qps|vscatterpf1dpd|vscatterpf1qpd|vfpclassps|vfpclasspd|vfpclassss|vfpclasssd|vrangeps|vrangepd|vrangess|vrangesd|vreduceps|vreducepd|vreducess|vreducesd|vpmovm2d|vpmovm2q|vpmovm2b|vpmovm2w|vpmovd2m|vpmovq2m|vpmovb2m|vpmovw2m|vpmullq|vpmadd52luq|vpmadd52huq|v4fmaddps|v4fmaddss|v4fnmaddps|v4fnmaddss|vp4dpwssd|vp4dpwssds|vpdpbusd|vpdpbusds|vpdpwssd|vpdpwssds|vpcompressb|vpcompressw|vpexpandb|vpexpandw|vpshld|vpshldv|vpshrd|vpshrdv|vpopcntd|vpopcntq|vpopcntb|vpopcntw|vpshufbitqmb|gf2p8affineinvqb|gf2p8affineqb|gf2p8mulb|vpclmulqdq|vaesdec|vaesdeclast|vaesenc|vaesenclast)\>/' binary.asm 

(Примечание: если gawk«границы в слове S \<и \>не работает для вас, вы можете заменить их простыми [ \t]Это может сделать скрипты работать в других версиях AWK, а также, как. nawk) .

Похожие вопросы