As a disclaimer, I have never used LLVM before. I’m currently writing a CPU emulator and I want to add JIT support. Right now, I am lifting the guest instructions to a custom IL, if I will use LLVM I will have to lift this IL to LLVM IR. The main things I am concerned about are indirect branching, thread-safety, and C compatibility. I’m wondering if LLVM will be good for the following use case:
To handle indirect branching I will need to exit the JIT, resolve the address, and lift the resulting address to my IL and then LLVM IR. I assume that there is a way to do this but I just wanted to make sure this is possible for I dive into LLVM.
Additionally, for each “function” that I JIT, I will need to pass in pointers to different structures in my emulator (guest memory base pointer, guest register bank, etc). I also assume this is possible but like I said I have never worked with LLVM so I’m not sure.
I am also wondering if the ORC JIT compiler is thread safe, I plan to have multiple emulators running in different threads (the use case is for fuzzing) and there could be a race condition if two emulator instances try to lift and JIT the same code. Can I have an ORC JIT running in each thread and or will there need to be one global ORC JIT that has a global lock associated with it?
The last thing that I would like is for the JIT to be accessible from LLVM’s C API. I did a cursory google search and it seems like the ORC JIT API is available from C but I would like to confirm this. I am writing this code in Rust and since Rust doesn’t have good ABI compatibility with C++, I’d really like for this to be available in C.
I realize I have a lot of requirements but I know LLVM will be able to generate better code that I could which is why I want to explore this option before I go and write a custom JIT from hand.
Thanks for taking the time to review and answer my questions!