AsmJit Project
Machine Code Generation for C++
AsmJit is a lightweight library for machine code generation written in C++ language. It can generate machine code for x86 and x64 architectures with the support for the whole x86/x64 instruction set - from legacy MMX to the newest AVX512 and AMX. It has a type-safe API that allows C++ compiler to do semantic checks at compile-time even before the assembled code is generated or executed. It also provides an optional register allocator that makes it easy to generate complex code without a significant development effort.
AsmJit project, as the name implies, started as a library to allow JIT code generation and execution. However, AsmJit evolved and now contains features that are far beyond the initial scope. AsmJit now consists of multiple projects:
The example below demonstrates how AsmJit separates concepts used during code generation. Check out AsmJit's documentation for more details and examples.
#include <asmjit/asmjit.h>
#include <stdio.h>
using namespace asmjit;
// Signature of the generated function.
typedef int (*Func)(void);
int main(int argc, char* argv[]) {
JitRuntime rt; // Runtime designed for JIT code execution.
CodeHolder code; // Holds code and relocation information.
code.init(rt.environment()); // Initialize CodeHolder to match JIT environment.
x86::Assembler a(&code); // Create and attach x86::Assembler to `code`.
a.mov(x86::eax, 1); // Move one to 'eax' register.
a.ret(); // Return from function.
// ----> x86::Assembler is no longer needed from here and can be destroyed <----
Func fn;
Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
if (err) return 1; // Handle a possible error returned by AsmJit.
// ----> CodeHolder is no longer needed from here and can be destroyed <----
int result = fn(); // Execute the generated code.
printf("%d\n", result); // Print the resulting "1".
// All classes use RAII, all resources will be released before `main()` returns,
// the generated function can be, however, released explicitly if you intend to
// reuse or keep the runtime alive, which you should in a production-ready code.
rt.release(fn);
return 0;
}
AsmJit has been used in various projects that required high performance code generation. Most of the time it's about generating specialized functions that implement calculations based on inputs that can change - this also includes scripting languages, recompilers, and machine learning. AsmJit has been the preferred choice for many people and companies because of its size and features.