The existing calli / callr interface is for ABI calls. Sometimes though
you want to call some of your own code, just to get the current return
address. ARM's branch-and-link instructions are ideal for this but they
don't exist on x86; there we emulate them by adding corresponding
pop_link_register / push_link_register instructions that are no-ops on
ARM.
* lightening.h (FOR_EACH_INSTRUCTION): Add jit_jmpi_with_link,
pop_link_register, push_link_register.
* lightening/arm-cpu.c:
* lightening/x86-cpu.c:
* lightening/aarch64-cpu.c (jmpi_with_link, push_link_register)
(pop_link_register): Add implementations.
* lightening/arm.h:
* lightening/aarch64.h:
* lightening/x86.h (JIT_LR): New definition.
* tests/link-register.c: New test.
This allows us to save and restore callee-save temporaries, i.e. RBP on
32-bit x86. Otherwise it's a disaster shuffling stack arguments using
temporaries.
The register structures just contain the regno. Since the only flag is
the callee-save flag, we can punt that to a separate per-backend,
per-target predicate.
Now that there's no hazard to using a register used for passing
arguments, renumber to give JIT_R/JIT_F/JIT_V names to all registers.
Choose a temp register that's not used for passing arguments. Our
previous choice was an argument register (doh!) which made function
calls with many arguments fail.
This improves integration with other projects. Like for example Guile
already has files named jit.c and jit.h; it's easier to manage if
lightening uses its own file names.