http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55171



Kai Tietz <ktietz at gcc dot gnu.org> changed:



           What    |Removed                     |Added

----------------------------------------------------------------------------

             Status|UNCONFIRMED                 |NEW

   Last reconfirmed|                            |2012-11-24

     Ever Confirmed|0                           |1



--- Comment #7 from Kai Tietz <ktietz at gcc dot gnu.org> 2012-11-24 12:47:37 
UTC ---

Yes, the issue here is the generation of patterns - like



movl    (%ecx), %eax

addl    -12(%eax), %ecx



- for thunks.



The following patch solves this issue for me.



Index: i386.c

===================================================================

--- i386.c    (Revision 193669)

+++ i386.c    (Arbeitskopie)

@@ -9567,6 +9567,8 @@

       tree decl = current_function_decl, fntype = TREE_TYPE (decl);

       bool fastcall_p

     = lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;

+      bool thiscall_p

+    = lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;

       bool static_chain_p = DECL_STATIC_CHAIN (decl);

       int regparm = ix86_function_regparm (fntype, decl);

       int drap_regno

@@ -9577,10 +9579,13 @@

       if ((regparm < 1 || (fastcall_p && !static_chain_p))

       && drap_regno != AX_REG)

     regno = AX_REG;

-      else if (regparm < 2 && drap_regno != DX_REG)

+      else if (thiscall_p

+                 && !static_chain_p && drap_regno != DX_REG)

+          regno = DX_REG;

+      else if (regparm < 2 && !thiscall_p && drap_regno != DX_REG)

     regno = DX_REG;

       /* ecx is the static chain register.  */

-      else if (regparm < 3 && !fastcall_p && !static_chain_p

+      else if (regparm < 3 && !fastcall_p && !thiscall_p && !static_chain_p

            && drap_regno != CX_REG)

     regno = CX_REG;

       else if (ix86_save_reg (BX_REG, true))

@@ -11092,12 +11097,15 @@

     return R11_REG;

   else

     {

-      bool is_fastcall;

+      bool is_fastcall, is_thiscall;

       int regparm;



       is_fastcall = (lookup_attribute ("fastcall",

                        TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))

              != NULL);

+      is_thiscall = (lookup_attribute ("thiscall",

+                       TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))

+             != NULL);

       regparm = ix86_function_regparm (TREE_TYPE (cfun->decl), cfun->decl);



       if (is_fastcall)

@@ -11110,6 +11118,12 @@

         }

       return AX_REG;

     }

+      else if (is_thiscall)

+        {

+      if (!DECL_STATIC_CHAIN (cfun->decl))

+        return DX_REG;

+      return AX_REG;

+    }

       else if (regparm < 3)

     {

       if (!DECL_STATIC_CHAIN (cfun->decl))

@@ -25046,7 +25060,7 @@



       fntype = TREE_TYPE (fndecl);

       ccvt = ix86_get_callcvt (fntype);

-      if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) != 0)

+      if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)

     {

       /* Fastcall functions use ecx/edx for arguments, which leaves

          us with EAX for the static chain.

@@ -25054,6 +25068,8 @@

          leaves us with EAX for the static chain.  */

       regno = AX_REG;

     }

+      else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)

+        regno = DX_REG;

       else if (ix86_function_regparm (fntype, fndecl) == 3)

     {

       /* For regparm 3, we have no free call-clobbered registers in

@@ -34713,8 +34729,10 @@

   else

     {

       unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function));

-      if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) != 0)

+      if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)

     tmp_regno = AX_REG;

+      else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)

+        tmp_regno = DX_REG;

       else

     tmp_regno = CX_REG;

     }

Reply via email to