diff --git a/.gitmodules b/.gitmodules index 0f897f3..4fb303e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,9 @@ [submodule "libjit/libjit"] path = libjit/libjit url = https://git.savannah.gnu.org/git/libjit.git +[submodule "mir/mir"] + path = mir/mir + url = https://github.com/vnmakarov/mir.git +[submodule "asmjit/asmjit"] + path = asmjit/asmjit + url = https://github.com/asmjit/asmjit.git diff --git a/Makefile b/Makefile index 48395aa..a9ba35f 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,8 @@ build-fib: build-fib-gcc \ build-fib-libgccjit \ build-fib-gnu-lightning \ build-fib-myjit \ - build-fib-libjit + build-fib-libjit \ + build-fib-asmjit build-fib-gcc: cd gcc && \ @@ -22,7 +23,11 @@ build-fib-libgccjit: build-fib-gnu-lightning: cd gnu_lightning && \ - gcc -O3 fib.c -o fib -llightning + gcc -O3 fib.c -o fib -llightning -Wl,-rpath -Wl,/usr/local/lib + +build-fib-asmjit: + cd asmjit && \ + g++ -O3 fib.cpp -o fib -lasmjit -Wl,-rpath -Wl,/usr/local/lib build-fib-myjit: cd myjit/myjit/ && \ @@ -37,20 +42,21 @@ build-fib-libjit: ./configure &&\ make cd libjit/ && \ - gcc -O3 -o fib fib.c libjit/jit/.libs/libjit.a -lm -pthread + gcc -O3 -o fib fib.c -Ilibjit/include libjit/jit/.libs/libjit.a -lm -pthread build-fib-mir: cd mir/ && \ - gcc -O3 -o fib fib-mir.c -lmir -lpthread + gcc -O3 -o fib fib-mir.c -Imir -Lmir -lmir -lpthread bench: bench-fib bench-fib: - hyperfine --warmup 3 \ + hyperfine -i -N --warmup 3 \ './libjit/fib' \ './libgccjit/toyvm ./libgccjit/fibonacci.toy 42' \ './mir/fib' \ './gnu_lightning/fib' \ + './asmjit/fib' \ './myjit/fib' \ './gcc/fib' \ './nasm/fib' diff --git a/asmjit/fib.cpp b/asmjit/fib.cpp new file mode 100644 index 0000000..3b515c0 --- /dev/null +++ b/asmjit/fib.cpp @@ -0,0 +1,63 @@ +#include +#include + +using namespace asmjit; + +// Signature of the generated function. +typedef uint32_t (*Fibonacci)(uint32_t x); + +int main(int argc, char *argv[]) +{ + JitRuntime rt; + CodeHolder code; + code.init(rt.environment(), rt.cpuFeatures()); + + x86::Compiler cc(&code); // Create and attach X86Compiler to `code`. + FuncSignature funcSign = FuncSignature::build(); + FuncNode* func = cc.newFunc(funcSign); + + Label L_Exit = cc.newLabel(); // Exit label. + x86::Gp x = cc.newUInt32(); // Function `x` argument. + x86::Gp y = cc.newUInt32(); // Temporary. + + cc.addFunc(func); + func->setArg(0, x); + + cc.cmp(x, 3); // Return `x` if less than 3. + cc.jb(L_Exit); + + cc.dec(x); // x' = x - 1 + cc.mov(y, x); // y = x' + cc.dec(y); // y = x - 2 + + Fibonacci fib; + + InvokeNode* call1; + cc.invoke(&call1, func->label(), funcSign); + call1->setArg(0, x); // `x` is an input argument + call1->setRet(0, x); // `x` receives return value + + InvokeNode* call2; + cc.invoke(&call2, func->label(), funcSign); + call2->setArg(0, y); // `y` is an input argument + call2->setRet(0, y); // `y` receives return value + + cc.add(x, y); // Combine the return value with `y`. + + cc.bind(L_Exit); + cc.ret(x); // Return `x`. + cc.endFunc(); // End of the function body. + + cc.finalize(); // Translate and assemble the whole `cc` content. + // ----> X86Compiler is no longer needed from here and can be destroyed <---- + + Error err = rt.add(&fib, &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 <---- + + printf("%d\n", fib(42)); + + rt.release(fib); // RAII, but let's make it explicit. + return 0; +} \ No newline at end of file diff --git a/mir/fib-mir.c b/mir/fib-mir.c index 692bcc6..b207653 100644 --- a/mir/fib-mir.c +++ b/mir/fib-mir.c @@ -2,11 +2,9 @@ #include "mir-gen.h" int main(void) { - const int thread = 0; - MIR_context_t ctx = MIR_init(); - MIR_gen_init(ctx, thread + 1); - MIR_gen_set_optimize_level(ctx, thread, 3 /*-O3*/); + MIR_gen_init(ctx); + MIR_gen_set_optimize_level(ctx, 3 /*-O3*/); MIR_module_t m = MIR_new_module(ctx, "m"); @@ -52,7 +50,7 @@ int main(void) { MIR_link(ctx, MIR_set_gen_interface, NULL); - void *gen = MIR_gen(ctx, thread, func); + void *gen = MIR_gen(ctx, func); uint64_t (*fibonacci)(uint64_t arg1) = (uint64_t(*)(uint64_t))gen; printf("%lu\n", (unsigned long)fibonacci(42)); diff --git a/mir/mir b/mir/mir new file mode 160000 index 0000000..99c6507 --- /dev/null +++ b/mir/mir @@ -0,0 +1 @@ +Subproject commit 99c65079038f3ba9242ef646f308c266cfd7a8e5