P2 ABI

Comments

I'm not sure what an ABI spec looks like, but p2gcc uses the same stack, heap and calling convention as PropGCC. Does PropGCC have an ABI spec? The registers and cog routines are defined in lib/prefix.spin2.

Is the P1 PropGCC calling convention really the best fit for the P2? The P2 has may features that I imagine would be good to leverage for a standard calling convention. For example, since there's an efficient way to do 16 long block transfer (there is, right?), it might be worth having it so that there are always 16 consecutive registers that are all pushed and pop with each call.

I'm not sure what an ABI spec looks like, but p2gcc uses the same stack, heap and calling convention as PropGCC. Does PropGCC have an ABI spec? The registers and cog routines are defined in lib/prefix.spin2.

My understanding is that prop-gcc uses the ARM calling convention, i.e. the propeller is seen as an ARM processor with all its registers, stack, etc.

I think we do need a discussion on the P2 ABI, and it probably needs to be P2 specific rather than being driven by what we did in PropGCC for P1. For example, on P2 it would make a lot of sense to use ptra or ptrb for the stack pointer register (fastspin uses ptra, but I'll happily change it to whatever becomes the standard).

@Cluso99 has defined how to call his ROM monitor (parameters passed in registers at the end of COG RAM, if I recall correctly). We could try to make p2gcc compatible with that, if it's general enough.

@cgracey, have you given any thought to how your Spin interpreter might call out to PASM routines?

My guess is that we'll probably have at least 2 calling conventions, one using the CALL instruction and the built-in 8 level stack, and another using a general stack (probably CALLA or CALLB). There could also be variations on "pass arguments in registers" or "pass arguments on the stack".

I feel like the 16 register ARM-like convention we used for Prop1 is probably too restrictive. In retrospect having more registers would have been better. Perhaps a 32 register, RISCV like calling convention would work.

My guess is that we'll probably have at least 2 calling conventions, one using the CALL instruction and the built-in 8 level stack, and another using a general stack (probably CALLA or CALLB). There could also be variations on "pass arguments in registers" or "pass arguments on the stack".

We also have the CALLD instruction that leaves the return address in a register and doesn't touch the stack. At one point we pushed hard to get this into P2 because we thought it would be the best instruction to use from GCC. Has that changed?

My guess is that we'll probably have at least 2 calling conventions, one using the CALL instruction and the built-in 8 level stack, and another using a general stack (probably CALLA or CALLB). There could also be variations on "pass arguments in registers" or "pass arguments on the stack".

We also have the CALLD instruction that leaves the return address in a register and doesn't touch the stack. At one point we pushed hard to get this into P2 because we thought it would be the best instruction to use from GCC. Has that changed?

No, CALLD is another good alternative. In a way we're presented with too many choices on P2. Coming up with an ABI that everyone will use is going to be a challenge.

p2gcc does use the CALLD instruction. It provides a similar function that the JMPRET instruction provides on the P1. There are 2 encodings for the CALLD instruction, and the more useful one allows for only 4 possible values for the D register. For that reason, p2gcc uses the PA register for the link register.