Hi, Gcc doesn't follow x86-64 psABI when passing and returing union with long double:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39082 Gcc converts X87UP to SSE if X87UP is not preceded by X87. I don't believe x86-64 psABI calls for it. I think psABI should be updated with: Index: low-level-sys-info.tex =================================================================== --- low-level-sys-info.tex (revision 5122) +++ low-level-sys-info.tex (working copy) @@ -452,7 +452,9 @@ types works as follows: \item Then a post merger cleanup is done: \begin{enumerate} \item If one of the classes is MEMORY, the whole argument is passed in memory. - \item If SSEUP is not preceeded by SSE, it is converted to SSE. + \item If X87UP is not preceded by X87, the whole argument is passed in + memory. + \item If SSEUP is not preceded by SSE, it is converted to SSE. \end{enumerate} \end{enumerate} The gcc patch is: --- ./i386.c.x87 2009-02-02 15:36:01.000000000 -0800 +++ ./i386.c 2009-02-02 15:58:57.000000000 -0800 @@ -4988,10 +4988,15 @@ classify_argument (enum machine_mode mod && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS)) classes[i] = X86_64_SSE_CLASS; - /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */ + /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS, + everything should be passed in memory. */ if (classes[i] == X86_64_X87UP_CLASS - && (i == 0 || classes[i - 1] != X86_64_X87_CLASS)) - classes[i] = X86_64_SSE_CLASS; + && (classes[i - 1] != X86_64_X87_CLASS)) + { + /* The first one should never be X86_64_X87UP_CLASS. */ + gcc_assert (i != 0); + return 0; + } } return words; } -- H.J.