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.

Reply via email to