There's very little mandated by the CPU that I can think of.
Not mandated by the CPU, but defined and documented by the CPU vendor.
Look, you can make any calling convention you want. If you don't use
the standard ABI defined by the MIPS architecture, though, no one will
interoperate with your code, or care about it.
which registers are caller-save and which are callee-save
and how return addresses are stored when a sub-sub-routine is called
etc are generally just conventions aren't they?
Sure.
But if you ignore those conventions, you have just eliminated any reason
for anyone to try to interoperate with your code, support your platform,
or otherwise interact with you at all.
I have two choices: I can spend half an hour adding flawless support for
someone who followed published standards, or I can spend months adding
buggy support for someone who ignored them. Which of these choices is going
to give me a better return on my time?
Besides, since we are focussing on the ABI, I think the mechanism
would probably be relevant to the CPU type, not to the OS as a whole.
In other words, one OS but each platform could have its own calling
conventions - the ones that were most appropriate for that hardware.
Why, yes. And that's the thing. If you target 64-bit mips, but don't use
the standard 64-bit ABI, you have chosen irrelevance preemptively. You're
basically guaranteed not to get any support or buy-in, and without that,
it's a purely academic research project.
I think I may have mislead people as that's not what I had in mind. As
explained in reply to others I can predict the basics of what C will
do with my code on a given architecture. If it makes things better
than I thought of that's fine. The key point is that it won't
(normally) do nasty things that I don't expect. I can't say that of
any other HLL.
I guess it depends on what you expect, doesn't it?
Consider:
int x, y = 3;
x = y;
Assume that int is 32 bits. How many instructions will be used to perform
this operation, and how much data will be loaded to or from registers or
memory?
Answers I've seen include:
* No instructions, because the optimizer discarded one or both of the
variables.
* No instructions, because the optimizer arranged for them to have the
right values in advance.
* Both are in registers.
* Neither is in a register.
* They're both in memory. To perform the operation, the compiler generates
code to load a 16-byte vector starting with y into one register, load
another 16-byte vector starting with x into another register, load an
immediate value into another register, use the immediate value to mask
the first four bytes of y into the first four bytes of x, then save that
16-byte chunk of memory back to main memory.
You may be right. The trouble is I don't know of anything better. Do
you?
I don't think there exists a good tool for developing a competing ABI in
the absence of a really, really, compelling argument that a better ABI is
needed.
-s