libobjc2
libobjc2 copied to clipboard
libobjc2 on risc-v
hi
is there any work on getting libobjc2 working on risc-v?
i tried to build libobjc2 on riscv64 linux and couldnt get it compiled because it seems most of the primitive functions require assembly implementations, of which risc-v seems missing...
if there is no way to compile without assembly, then those parts would need to be implemented... is anyone already working on those?
if help is needed id by happy to collaborate!
please let me know, and thanks in advance ^^
I'm not actively working on it, but I'm happy to review a PR. You will need to modify three places:
- block_trampolines.S needs to have a pair of functions (one for the normal calling convention, one for the structure-on-the-stack-allocated-by-the-caller return [sret] calling convention). This needs to move the first argument (the object) over the second (the selector in the caller) and load the block from the page before.
- objc_msgSend.riscv.S (objc_msgSend.mips.S is probably the closest. This is fairly well commented, so you can hopefully understand what it needs to do quite easily, feel free to ping me if it isn't.
- objc_msgSend.S needs to be modified to include the correct version for RISC-V.
The message-send logic needs to:
- Check if the receiver is 0, if so return nil (may need to be different for integer / FP returns, but I believe RISC-V can just return integer and floating point, but does need to zero all return registers). For the structure-return variants, no extra logic is necessary, the compiler zeroes the structure.
- Check if the low bit (32-bit) or 3 bits (64-bit) are zero. If not, then find the class from the
SmallObjectClasses
array (64-bit) orSmallIntClass
(32-bit) global, otherwise load it from theisa
pointer. - Load the dtable pointer from the class, then follow the chain of these until you reach the method.
- If this is non-null, jump to it.
- If this is null, we are on a slow path:
- Spill all argument registers (we can't tell which are in use, so we need to spill any register that can be an argument register, including any vector ones).
- Call the slow-path forwarding function
slowMsgLookup
. This takes the address of the receiver as an argument because it can rewrite the receiver (e.g. for-forwardingTargetForSelector
). - Restore all arguments. Typically, if you spill the receiver as an argument you can pass the on-stack spill address in step 2 here and not need any special-case logic for restoring it.
- Jump to the pointer that it returns.
@davidchisnall
thanks for the super detailed reply, especially for the message-send logic
ill try to take a look at what i can do over the weekend, and if i have any progress or issue ill come back here if its ok with you (ill try not to bother with anything trivial)
thank you again!
See https://github.com/gnustep/libobjc2/pull/261