x86lint examines x86 machine code to find suboptimal encodings and sequences.
For example, add eax, 1
can encode with either an 8- or 32-bit immediate:
83C0 01
81C0 01000000
Using the former can result in smaller and faster code. x86lint can help compiler writers generate better code and documents the complexity of x86.
- implicit EAX
81C0 00010000
instead of05 00010000
(ADD EAX, 0x100)
- missing LOCK prefix on CMPXCHG and XADD
- oversized immediates
81C0 01000000
instead of83C0 01
(ADD EAX, 1)
- strength-reduce AND with immediate to MOVZBL
- suboptimal CMP 0
83FF 00
instead of TEST85C0
- suboptimal no-ops
- multiple
90
instead of a single60 90
, etc.
- multiple
suboptimal zero register, see #7- MOV EAX, 0 instead of XOR EAX, EAX
- unnecessary REX prefix
- XOR RAX, RAX
4831C0
instead of XOR EAX, EAX31C0
40C9
instead ofC9
(LEAVE)
- XOR RAX, RAX
- unnecessary immediate
C1D0 01
instead ofD1D0
(RCL EAX, 1)
- unneeded LOCK prefix on XCHG
First install the Intel x86 encoder decoder:
git clone https://github.com/intelxed/xed.git xed
git clone https://github.com/intelxed/mbuild.git mbuild
cd xed
./mfile.py install --install-dir=kits/xed-install
Next build x86lint:
git clone https://github.com/gaul/x86lint.git x86lint
cd x86lint
XED_PATH=/path/to/xed make all
x86lint is intended to be part of compiler test suites which should #include "x86lint.h"
and link libx86lint.a
. It can also read arbitrary ELF executables via:
./x86lint /bin/ls
- Agner Fog optimization guide
- Intel instruction set reference
- Intel optimization manual
- Intel x86 encoder decoder - library to parse instructions
Copyright (C) 2018 Andrew Gaul
Licensed under the Apache License, Version 2.0