ld-linux.so
In glibc/sysdeps/ia64/dl-machine.h the macro TRAMPOLINE_TEMPLATE saves the input registers but not r8 (pointer to value returned in memory). r8 should be preserved across the runtime fixup.
The following example fails on linux-ia64:
foo.hpp:
===
class foo {
public:
long _a;
long _b;
foo(long a, long b) : _a(a), _b(b) {}
};
extern foo bar(long a, long b);
bar.cpp:
===
#include "foo.hpp"
foo bar(long a, long b) { return foo(a, b); }
foo.cpp:
===
#include <stdlib.h>
#include <stdio.h>
#include "foo.hpp"
int main() {
foo f = bar(1, 2);
fprintf(stdout, "a=%ld, b=%ld\n", f._a, f._b);
return EXIT_SUCCESS;
}
$ g++ -fPIC -shared -o libbar.so bar.cpp $ g++ -o foo foo.cpp -L. -lbar
-Laurent
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Laurent" = Laurent Morichetti <[email protected]> writes:
Laurent> In glibc/sysdeps/ia64/dl-machine.h the macro Laurent> TRAMPOLINE_TEMPLATE saves the input registers but not r8 Laurent> (pointer to value returned in memory). r8 should be preserved Laurent> across the runtime fixup.
I know very little about the C++ ABI so this may be C++ specific. I thought r8 was meant to be a return register and not an input register and that it's valid to clobber it in any function call, whether the function returns a value or void?
I am sitting at home right now and all my documents are in the office so I can't look it up.
Jes
Quoted 9 lines · Jes Sorensen
Laurent> In
glibc/sysdeps/ia64/dl-machine.hthe macro Laurent>TRAMPOLINE_TEMPLATEsaves the input registers but not r8 Laurent> (pointer to value returned in memory). r8 should be preserved Laurent> across the runtime fixup.I know very little about the C++ ABI so this may be C++ specific. I thought r8 was meant to be a return register and not an input register and that it's valid to clobber it in any function call, whether the function returns a value or void?
When the function in question returns an (non-HFA) aggregate that's larger than 32 bytes (256 bits), r8 is an input register containing the address of the region of memory into which to write the return structure. When this is the case, r8 is not an output register. I.e, the calling conventions do not mandate restoring the struct address.
When the aggregate happens to be an HFA, the HFA is returned in floating point registers f8 thru f15 for HFAs of up to 8 elements. When they're larger than 8 elements, the above convention regarding r8 is used.
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Kevin" = Kevin Buettner <[email protected]> writes:
Quoted 4 lines · Jes Sorensen
Quoted 4 lines
I know very little about the C++ ABI so this may be C++ specific.
I thought r8 was meant to be a return register and not an input register and that it's valid to clobber it in any function call, whether the function returns a value or void?
Kevin> When the function in question returns an (non-HFA) aggregate Kevin> that's larger than 32 bytes (256 bits), r8 is an input register Kevin> containing the address of the region of memory into which to Kevin> write the return structure. When this is the case, r8 is not Kevin> an output register. I.e, the calling conventions do not Kevin> mandate restoring the struct address.
ARGH!
Thats nasty, I would much have preferred to see something like r32 used as the input pointer and have it returned in r8 afterwards. This way it is going to cause overhead on every single lookup ;-(
Well it's still a bug so we better fix it.
Jes
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
"Jes" = Jes Sorensen <[email protected]> writes:
"Kevin" = Kevin Buettner <[email protected]> writes:
Quoted 4 lines · Jes Sorensen
Quoted 4 lines
Quoted 4 lines
I know very little about the C++ ABI so this may be C++ specific. I thought r8 was meant to be a return register and not an input register and that it's valid to clobber it in any function call, whether the function returns a value or void?
Kevin> When the function in question returns an (non-HFA) aggregate Kevin> that's larger than 32 bytes (256 bits), r8 is an input register Kevin> containing the address of the region of memory into which to Kevin> write the return structure. When this is the case, r8 is not Kevin> an output register. I.e, the calling conventions do not Kevin> mandate restoring the struct address.
Jes> ARGH!
Jes> Thats nasty, I would much have preferred to see something like Jes> r32 used as the input pointer and have it returned in r8 Jes> afterwards. This way it is going to cause overhead on every Jes> single lookup ;-(
Hmmm ok, a bit of overreacting since we can store r8 in a local register, we don't need to flush it onto the stack as I was thinking at first.
However, I just checked the code and r8 is already being saved in loc2 across the lookup call. I suspect this was put in when Richard Henderson optimized the packaging of the bundles.
Jes