Hi,

adjusted patch to make it more bullet-proved and tested it.

2014-05-26  Kai Tietz  <kti...@redhat.com>

        * config/i386/i386.c (ix86_expand_call): Enforce for sibcalls
        on memory the use of accumulator-register.
        (ix86_function_ok_for_sibcall): Reject for x86_64 ABI sibling
        calls for varardic-functions.

Regression tested for x86_64-unknown-linux-gnu, x86_64-w64-mingw32, and 
i686-pc-cygwin.
Ok for apply?

Regards,
Kai


Index: i386.c
===================================================================
--- i386.c      (revision 210936)
+++ i386.c      (working copy)
@@ -5298,6 +5298,12 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
       decl_or_type = type;
     }
 
+  /* We need to reject stdarg-function for x86_64 ABI as accumulator
+     is used as argument.  */
+  if (TARGET_64BIT && stdarg_p (type)
+      && ix86_function_type_abi (type) == SYSV_ABI)
+    return false;
+
   /* Check that the return value locations are the same.  Like
      if we are returning floats on the 80387 register stack, we cannot
      make a sibcall from a function that doesn't return a float to a
@@ -24916,8 +24922,19 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx call
           ? !sibcall_insn_operand (XEXP (fnaddr, 0), word_mode)
           : !call_insn_operand (XEXP (fnaddr, 0), word_mode))
     {
+      rtx r;
       fnaddr = convert_to_mode (word_mode, XEXP (fnaddr, 0), 1);
-      fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (word_mode, fnaddr));
+      if (!sibcall)
+       r = copy_to_mode_reg (word_mode, fnaddr);
+      else
+       {
+         r = gen_rtx_REG (word_mode, AX_REG);
+         if (! general_operand (fnaddr, VOIDmode))
+                   fnaddr = force_operand (fnaddr, r);
+         if (fnaddr != r)
+           emit_move_insn (r, fnaddr);
+       }
+      fnaddr = gen_rtx_MEM (QImode, r);
     }
 
   call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);

Reply via email to