And those compilers have to perform that optimization, because their languages don't support true multiple return-values.
I'm gonna have to disagree with this one
It's not a matter of "have to", it's just that like almost ALL languages, the literal conversion of lines in the language to machine code is not the most efficient way to do the job. Any language that "truly" supports multiple return values is probably just putting pretty syntax on what C/C++ does anyway, after all odds are, that compiler for your language was probably _written_ in C/C++
. So here's the thing.
First of all, I'm not quite sure what people are expecting with multiple return value, the way I see it, if the data to be returned is larger than a register, there are 3 options (there are perhaps more, but this is all that comes to mine at the moment):
(note intel specific examples, but concept applies to all cpus generally)
1. use several registers, not just EAX for the return value, in the example of a struct with 2 int elements, EAX:EDX would be sufficient, in fact Intel itself does this with a few 64-bit result opcodes (IMUL). The downside is that it only works for structures that are this small, you are potentially adding more registers to clean up (push/pop them to preserve original value), and there are a finite number of registers, so this technique only works up to about 24/28 bytes (esp clearly can't be used ebp maybe if not used as a frame pointer).
2. The obvious return a pointer. OK, well if the struct is bigger than 2 or so registers, odds are it's gonna be in RAM anyway till the end of it's scope, so why not just pass a pointer to it? It's already in RAM, a pointer fits in a register, and you'd need to read it from memory anyway, no huge loss, plus this works for all sizes. There is potentially a little memory cleanup with restoring ESP to it's original value, but odds are we had to do that anyway.
3. return direct to object. This is a nice trick, basically the compiler says, well i was gonna make this temp object, but i see you are just gonna copy the data and then this temp is gonna go away anyway, so why don't we eliminate the middle man. Once again works in the general case.
So my question is this:
In the languages that do "truly support" multiple return values, how do you intend to implement this feature on a assembly level? I mean, odds are you'll have to resort to one of these techniques mentioned above, in which case you are just putting a prettier syntax on top of C/C++'s approach. As mentioned above #1 is OK for this, but not general purpose, so it's only usable in some cases, would it be your solution anyway? If so, what would you want if the data is bigger than the registers can provide storage for?
proxy