OSDN Git Service

2008-06-03 Kai Tietz <kai.tietz@onevision.com>
authorktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Jun 2008 08:05:25 +0000 (08:05 +0000)
committerktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Jun 2008 08:05:25 +0000 (08:05 +0000)
* doc/tm.texi (OVERRIDE_ABI_FORMAT): New.
* doc/extend.texi (ms_abi,sysv_abi): New attribute description.
* function.c (allocate_struct_function): Use of
OVERRIDE_ABI_FORMAT.
* config/i386/cygming.h (TARGET_64BIT_MS_ABI): Make use
of cfun and DEFAULT_ABI to deceide abi mode.
(DEFAULT_ABI): New.
(REG_PARM_STACK_SPACE): Removed.
(OUTGOING_REG_PARM_STACK_SPACE): Removed.
(STACK_BOUNDARY): Use default target to deceide stack boundary.
* config/i386/i386-protos.h (ix86_cfun_abi): New.
(ix86_function_abi): Likewise.
(ix86_function_type_abi): Likewise.
(ix86_call_abi_override): Likewise.
* confid/i386/i386.md (SSE_REGPARM_MAX): Replaced by abi
specific define X86_64_SSE_REGPARM_MAX/X64_SSE_REGPARM_MAX.
* config/i386/i386.c (override_options): Replace TARGET_64BIT_MS_ABI.
(X86_64_VARARGS_SIZE): Replace REGPARM_MAX and SSE_REGPARM_MAX by abi
specific defines.
(X86_64_REGPARM_MAX): New.
(X86_64_SSE_REGPARM_MAX): New.
(X64_REGPARM_MAX): New.
(X64_SSE_REGPARM_MAX): New.
(X86_32_REGPARM_MAX): New.
(X86_32_SSE_REGPARM_MAX): New.
(ix86_handle_cconv_attribute): Replace TARGET_64BIT_MS_ABI.
(ix86_function_regparm): Handle user calling abi.
(ix86_function_arg_regno_p): Replace TARGET_64BIT_MS_ABI
by DEFAULT_ABI versus SYSV_ABI check.
(ix86_reg_parm_stack_space): New.
(ix86_function_type_abi): New.
(ix86_call_abi_override): New.
(ix86_function_abi): New.
(ix86_cfun_abi): New.
(init_cumulative_args): Call abi specific initialization.
(function_arg_advance): Remove TARGET_64BIT_MS_ABI.
(function_arg_64): Extend SSE_REGPARM_MAX check.
(function_arg (): Remove TARGET_64BIT_MS_ABI.
(ix86_pass_by_reference): Likewise.
(ix86_function_value_regno_p): Likewise.
(function_value_64): Replace REGPARM_MAX, and SSE_REGPARM_MAX.
(ix86_function_value_1): Replace TARGET_64BIT_MS_ABI.
(return_in_memory_ms_64): Replace TARGET_64BIT_MS_ABI.
(ix86_build_builtin_va_list): Replace TARGET_64BIT_MS_ABI.
(setup_incoming_varargs_64): Adjust regparm for call abi.
(ix86_setup_incoming_varargs): Replace TARGET_64BIT_MS_ABI.
(ix86_va_start): Likewise.
(ix86_gimplify_va_arg): Likewise.
(ix86_expand_prologue): Likewise.
(output_pic_addr_const): Likewise.
(ix86_init_machine_status): Initialize call_abi by DEFAULT_ABI.
(x86_this_parameter): Replace TARGET_64BIT_MS_ABI.
(x86_output_mi_thunk): Likewise.
(x86_function_profiler): Likewise.
* config/i386/i386.h (TARGET_64BIT_MS_ABI): Use ix64_cfun_abi.
(SYSV_ABI, MS_ABI): New constants.
(DEFAULT_ABI): New.
(init_regs): Add prototype of function in regclass.c file.
(OVERRIDE_ABI_FORMAT): New.
(CONDITIONAL_REGISTER_USAGE): Remove TARGET_64BIT_MS_ABI part.
(REG_PARM_STACK_SPACE): Use ix86_reg_parm_stack_space.
(OUTGOING_REG_PARM_STACK_SPACE): New.
(ix86_reg_parm_stack_space): New prototype.
(CUMULATIVE_ARGS): Add call_abi member.
(machine_function): Add call_abi member.
* config/i386/mingw32.h (EXTRA_OS_CPP_BUILTINS): Replace TARGET_64BIT_MS_ABI
by DEFAULT_ABI compare to MS_ABI.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@136311 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/cygming.h
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md
gcc/config/i386/mingw32.h
gcc/doc/extend.texi
gcc/doc/tm.texi
gcc/function.c
gcc/target-def.h

index 56b6ddb..7f75646 100644 (file)
@@ -1,3 +1,73 @@
+2008-06-03  Kai Tietz  <kai.tietz@onevision.com>
+
+       * doc/tm.texi (OVERRIDE_ABI_FORMAT): New.
+       * doc/extend.texi (ms_abi,sysv_abi): New attribute description.
+       * function.c (allocate_struct_function): Use of
+       OVERRIDE_ABI_FORMAT.
+       * config/i386/cygming.h (TARGET_64BIT_MS_ABI): Make use
+       of cfun and DEFAULT_ABI to deceide abi mode.
+       (DEFAULT_ABI): New.
+       (REG_PARM_STACK_SPACE): Removed.
+       (OUTGOING_REG_PARM_STACK_SPACE): Removed.
+       (STACK_BOUNDARY): Use default target to deceide stack boundary.
+       * config/i386/i386-protos.h (ix86_cfun_abi): New.
+       (ix86_function_abi): Likewise.
+       (ix86_function_type_abi): Likewise.
+       (ix86_call_abi_override): Likewise.
+       * confid/i386/i386.md (SSE_REGPARM_MAX): Replaced by abi
+       specific define X86_64_SSE_REGPARM_MAX/X64_SSE_REGPARM_MAX.
+       * config/i386/i386.c (override_options): Replace TARGET_64BIT_MS_ABI.
+       (X86_64_VARARGS_SIZE): Replace REGPARM_MAX and SSE_REGPARM_MAX by abi
+       specific defines.
+       (X86_64_REGPARM_MAX): New.
+       (X86_64_SSE_REGPARM_MAX): New.
+       (X64_REGPARM_MAX): New.
+       (X64_SSE_REGPARM_MAX): New.
+       (X86_32_REGPARM_MAX): New.
+       (X86_32_SSE_REGPARM_MAX): New.
+       (ix86_handle_cconv_attribute): Replace TARGET_64BIT_MS_ABI.
+       (ix86_function_regparm): Handle user calling abi.
+       (ix86_function_arg_regno_p): Replace TARGET_64BIT_MS_ABI
+       by DEFAULT_ABI versus SYSV_ABI check.
+       (ix86_reg_parm_stack_space): New.
+       (ix86_function_type_abi): New.
+       (ix86_call_abi_override): New.
+       (ix86_function_abi): New.
+       (ix86_cfun_abi): New.
+       (init_cumulative_args): Call abi specific initialization.
+       (function_arg_advance): Remove TARGET_64BIT_MS_ABI.
+       (function_arg_64): Extend SSE_REGPARM_MAX check.
+       (function_arg (): Remove TARGET_64BIT_MS_ABI.
+       (ix86_pass_by_reference): Likewise.
+       (ix86_function_value_regno_p): Likewise.
+       (function_value_64): Replace REGPARM_MAX, and SSE_REGPARM_MAX.
+       (ix86_function_value_1): Replace TARGET_64BIT_MS_ABI.
+       (return_in_memory_ms_64): Replace TARGET_64BIT_MS_ABI.
+       (ix86_build_builtin_va_list): Replace TARGET_64BIT_MS_ABI.
+       (setup_incoming_varargs_64): Adjust regparm for call abi.
+       (ix86_setup_incoming_varargs): Replace TARGET_64BIT_MS_ABI.
+       (ix86_va_start): Likewise.
+       (ix86_gimplify_va_arg): Likewise.
+       (ix86_expand_prologue): Likewise.
+       (output_pic_addr_const): Likewise.
+       (ix86_init_machine_status): Initialize call_abi by DEFAULT_ABI.
+       (x86_this_parameter): Replace TARGET_64BIT_MS_ABI.
+       (x86_output_mi_thunk): Likewise.
+       (x86_function_profiler): Likewise.
+       * config/i386/i386.h (TARGET_64BIT_MS_ABI): Use ix64_cfun_abi.
+       (SYSV_ABI, MS_ABI): New constants.
+       (DEFAULT_ABI): New.
+       (init_regs): Add prototype of function in regclass.c file.
+       (OVERRIDE_ABI_FORMAT): New.
+       (CONDITIONAL_REGISTER_USAGE): Remove TARGET_64BIT_MS_ABI part.
+       (REG_PARM_STACK_SPACE): Use ix86_reg_parm_stack_space.
+       (OUTGOING_REG_PARM_STACK_SPACE): New.
+       (ix86_reg_parm_stack_space): New prototype.
+       (CUMULATIVE_ARGS): Add call_abi member.
+       (machine_function): Add call_abi member.
+       * config/i386/mingw32.h (EXTRA_OS_CPP_BUILTINS): Replace TARGET_64BIT_MS_ABI
+       by DEFAULT_ABI compare to MS_ABI.
+
 2008-06-02  Andy Hutchinson  <hutchinsonandy@aim.com> 
 
        PR target/34879
 2008-06-02  Andy Hutchinson  <hutchinsonandy@aim.com> 
 
        PR target/34879
index bf46cab..1070c85 100644 (file)
@@ -34,7 +34,10 @@ along with GCC; see the file COPYING3.  If not see
 #endif
 
 #undef TARGET_64BIT_MS_ABI
 #endif
 
 #undef TARGET_64BIT_MS_ABI
-#define TARGET_64BIT_MS_ABI TARGET_64BIT
+#define TARGET_64BIT_MS_ABI (!cfun ? DEFAULT_ABI == MS_ABI : TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
+
+#undef DEFAULT_ABI
+#define DEFAULT_ABI (TARGET_64BIT ? MS_ABI : SYSV_ABI)
 
 #undef DBX_REGISTER_NUMBER
 #define DBX_REGISTER_NUMBER(n)                         \
 
 #undef DBX_REGISTER_NUMBER
 #define DBX_REGISTER_NUMBER(n)                         \
@@ -123,18 +126,6 @@ along with GCC; see the file COPYING3.  If not see
 #undef LONG_TYPE_SIZE
 #define LONG_TYPE_SIZE 32
 \f
 #undef LONG_TYPE_SIZE
 #define LONG_TYPE_SIZE 32
 \f
-#undef REG_PARM_STACK_SPACE
-#define REG_PARM_STACK_SPACE(FNDECL) (TARGET_64BIT_MS_ABI ? 32 : 0)
-
-#undef OUTGOING_REG_PARM_STACK_SPACE
-#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) (TARGET_64BIT_MS_ABI ? 1 : 0)
-
-#undef REGPARM_MAX
-#define REGPARM_MAX (TARGET_64BIT_MS_ABI ? 4 : 3)
-
-#undef SSE_REGPARM_MAX
-#define SSE_REGPARM_MAX (TARGET_64BIT_MS_ABI ? 4 : TARGET_SSE ? 3 : 0)
-\f
 /* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop).  */
 #define HANDLE_PRAGMA_PACK_PUSH_POP 1
 /* Enable push_macro & pop_macro */
 /* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop).  */
 #define HANDLE_PRAGMA_PACK_PUSH_POP 1
 /* Enable push_macro & pop_macro */
@@ -214,7 +205,7 @@ do {                                                \
 #define CHECK_STACK_LIMIT 4000
 
 #undef STACK_BOUNDARY
 #define CHECK_STACK_LIMIT 4000
 
 #undef STACK_BOUNDARY
-#define STACK_BOUNDARY (TARGET_64BIT_MS_ABI ? 128 : BITS_PER_WORD)
+#define STACK_BOUNDARY (DEFAULT_ABI == MS_ABI ? 128 : BITS_PER_WORD)
 
 /* By default, target has a 80387, uses IEEE compatible arithmetic,
    returns float values in the 387 and needs stack probes.
 
 /* By default, target has a 80387, uses IEEE compatible arithmetic,
    returns float values in the 387 and needs stack probes.
index 6fdea06..a92272b 100644 (file)
@@ -137,6 +137,11 @@ extern int ix86_function_arg_boundary (enum machine_mode, tree);
 extern bool ix86_sol10_return_in_memory (const_tree,const_tree);
 extern rtx ix86_force_to_memory (enum machine_mode, rtx);
 extern void ix86_free_from_memory (enum machine_mode);
 extern bool ix86_sol10_return_in_memory (const_tree,const_tree);
 extern rtx ix86_force_to_memory (enum machine_mode, rtx);
 extern void ix86_free_from_memory (enum machine_mode);
+extern int ix86_cfun_abi (void);
+extern int ix86_function_abi (const_tree);
+extern int ix86_function_type_abi (const_tree);
+extern void ix86_call_abi_override (const_tree);
+
 extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
                                  rtx, rtx, rtx, rtx);
 extern bool ix86_hard_regno_mode_ok (int, enum machine_mode);
 extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
                                  rtx, rtx, rtx, rtx);
 extern bool ix86_hard_regno_mode_ok (int, enum machine_mode);
index 16e7422..b159ce4 100644 (file)
@@ -1619,7 +1619,7 @@ rtx ix86_compare_op1 = NULL_RTX;
 rtx ix86_compare_emitted = NULL_RTX;
 
 /* Size of the register save area.  */
 rtx ix86_compare_emitted = NULL_RTX;
 
 /* Size of the register save area.  */
-#define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
+#define X86_64_VARARGS_SIZE (X86_64_REGPARM_MAX * UNITS_PER_WORD + X86_64_SSE_REGPARM_MAX * 16)
 
 /* Define the structure for the machine field in struct function.  */
 
 
 /* Define the structure for the machine field in struct function.  */
 
@@ -2306,11 +2306,11 @@ override_options (void)
     }
   else
     {
     }
   else
     {
-      /* For TARGET_64BIT_MS_ABI, force pic on, in order to enable the
+      /* For TARGET_64BIT and MS_ABI, force pic on, in order to enable the
         use of rip-relative addressing.  This eliminates fixups that
         would otherwise be needed if this object is to be placed in a
         DLL, and is essentially just as efficient as direct addressing.  */
         use of rip-relative addressing.  This eliminates fixups that
         would otherwise be needed if this object is to be placed in a
         DLL, and is essentially just as efficient as direct addressing.  */
-      if (TARGET_64BIT_MS_ABI)
+      if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)
        ix86_cmodel = CM_SMALL_PIC, flag_pic = 1;
       else if (TARGET_64BIT)
        ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
        ix86_cmodel = CM_SMALL_PIC, flag_pic = 1;
       else if (TARGET_64BIT)
        ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
@@ -2761,8 +2761,9 @@ override_options (void)
     set_param_value ("l2-cache-size", ix86_cost->l2_cache_size);
 
   /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
     set_param_value ("l2-cache-size", ix86_cost->l2_cache_size);
 
   /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
-     can be optimized to ap = __builtin_next_arg (0).  */
-  if (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
+     can be optimized to ap = __builtin_next_arg (0).
+     For abi switching it should be corrected.  */
+  if (!TARGET_64BIT || DEFAULT_ABI == MS_ABI)
     targetm.expand_builtin_va_start = NULL;
 
 #ifdef USE_IX86_CLD
     targetm.expand_builtin_va_start = NULL;
 
 #ifdef USE_IX86_CLD
@@ -3166,7 +3167,7 @@ ix86_handle_cconv_attribute (tree *node, tree name,
   if (TARGET_64BIT)
     {
       /* Do not warn when emulating the MS ABI.  */
   if (TARGET_64BIT)
     {
       /* Do not warn when emulating the MS ABI.  */
-      if (!TARGET_64BIT_MS_ABI)
+      if (TREE_CODE (*node) != FUNCTION_TYPE || !ix86_function_type_abi (*node))
        warning (OPT_Wattributes, "%qs attribute ignored",
                 IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
        warning (OPT_Wattributes, "%qs attribute ignored",
                 IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
@@ -3269,7 +3270,11 @@ ix86_function_regparm (const_tree type, const_tree decl)
   static bool error_issued;
 
   if (TARGET_64BIT)
   static bool error_issued;
 
   if (TARGET_64BIT)
-    return regparm;
+    {
+      if (ix86_function_type_abi (type) == DEFAULT_ABI)
+        return regparm;
+      return DEFAULT_ABI != SYSV_ABI ? X86_64_REGPARM_MAX : X64_REGPARM_MAX;
+    }
 
   attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
   if (attr)
 
   attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
   if (attr)
@@ -3500,15 +3505,20 @@ ix86_function_arg_regno_p (int regno)
         return true;
     }
 
         return true;
     }
 
+  /* TODO: The function should depend on current function ABI but
+     builtins.c would need updating then. Therefore we use the
+     default ABI.  */
+
   /* RAX is used as hidden argument to va_arg functions.  */
   /* RAX is used as hidden argument to va_arg functions.  */
-  if (!TARGET_64BIT_MS_ABI && regno == AX_REG)
+  if (DEFAULT_ABI == SYSV_ABI && regno == AX_REG)
     return true;
 
     return true;
 
-  if (TARGET_64BIT_MS_ABI)
+  if (DEFAULT_ABI == MS_ABI)
     parm_regs = x86_64_ms_abi_int_parameter_registers;
   else
     parm_regs = x86_64_int_parameter_registers;
     parm_regs = x86_64_ms_abi_int_parameter_registers;
   else
     parm_regs = x86_64_int_parameter_registers;
-  for (i = 0; i < REGPARM_MAX; i++)
+  for (i = 0; i < (DEFAULT_ABI == MS_ABI ? X64_REGPARM_MAX
+                                        : X86_64_REGPARM_MAX); i++)
     if (regno == parm_regs[i])
       return true;
   return false;
     if (regno == parm_regs[i])
       return true;
   return false;
@@ -3529,6 +3539,98 @@ ix86_must_pass_in_stack (enum machine_mode mode, const_tree type)
          && type && TREE_CODE (type) != VECTOR_TYPE);
 }
 
          && type && TREE_CODE (type) != VECTOR_TYPE);
 }
 
+/* It returns the size, in bytes, of the area reserved for arguments passed
+   in registers for the function represented by fndecl dependent to the used
+   abi format.  */
+unsigned int
+ix86_reg_parm_stack_space (const_tree fndecl)
+{
+  int call_abi = 0;
+  /* For libcalls it is possible that there is no fndecl at hand.
+     Therefore assume for this case the default abi of the target.  */
+  if (!fndecl)
+    call_abi = DEFAULT_ABI;
+  else
+    call_abi = ix86_function_abi (fndecl);
+  if (call_abi == 1)
+    return 32;
+  return 0;
+}
+
+/* Returns value SYSV_ABI, MS_ABI dependent on fntype, specifying the
+   call abi used.  */
+int
+ix86_function_type_abi (const_tree fntype)
+{
+  if (TARGET_64BIT && fntype != NULL)
+    {
+      int abi;
+      if (DEFAULT_ABI == SYSV_ABI)
+        abi = lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)) ? MS_ABI : SYSV_ABI;
+      else
+        abi = lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)) ? SYSV_ABI : MS_ABI;
+
+      if (DEFAULT_ABI == MS_ABI && abi == SYSV_ABI)
+        sorry ("using sysv calling convention on target w64 is not supported");
+
+      return abi;
+    }
+  return DEFAULT_ABI;
+}
+
+int
+ix86_function_abi (const_tree fndecl)
+{
+  if (! fndecl)
+    return DEFAULT_ABI;
+  return ix86_function_type_abi (TREE_TYPE (fndecl));
+}
+
+/* Returns value SYSV_ABI, MS_ABI dependent on cfun, specifying the
+   call abi used.  */
+int
+ix86_cfun_abi (void)
+{
+  if (! cfun || ! TARGET_64BIT)
+    return DEFAULT_ABI;
+  return cfun->machine->call_abi;
+}
+
+/* regclass.c  */
+extern void init_regs (void);
+
+/* Implementation of call abi switching target hook. Specific to FNDECL
+   the specific call register sets are set. See also CONDITIONAL_REGISTER_USAGE
+   for more details.
+   To prevent redudant calls of costy function init_regs (), it checks not to
+   reset register usage for default abi.  */
+void
+ix86_call_abi_override (const_tree fndecl)
+{
+  if (fndecl == NULL_TREE)
+    cfun->machine->call_abi = DEFAULT_ABI;
+  else
+    cfun->machine->call_abi = ix86_function_type_abi (TREE_TYPE (fndecl));
+  if (TARGET_64BIT && cfun->machine->call_abi == MS_ABI && call_used_regs)
+    {
+      if (call_used_regs[4 /*RSI*/] != 0 || call_used_regs[5 /*RDI*/] != 0)
+        {
+          call_used_regs[4 /*RSI*/] = 0;
+          call_used_regs[5 /*RDI*/] = 0;
+          init_regs ();
+        }
+    }
+  else if (TARGET_64BIT && call_used_regs)
+    {
+      if (call_used_regs[4 /*RSI*/] != 1 || call_used_regs[5 /*RDI*/] != 1)
+        {
+          call_used_regs[4 /*RSI*/] = 1;
+          call_used_regs[5 /*RDI*/] = 1;
+          init_regs ();
+        }
+    }
+}
+
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
    for a call to a function whose data type is FNTYPE.
    For a library call, FNTYPE is 0.  */
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
    for a call to a function whose data type is FNTYPE.
    For a library call, FNTYPE is 0.  */
@@ -3542,10 +3644,25 @@ init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
   struct cgraph_local_info *i = fndecl ? cgraph_local_info (fndecl) : NULL;
   memset (cum, 0, sizeof (*cum));
 
   struct cgraph_local_info *i = fndecl ? cgraph_local_info (fndecl) : NULL;
   memset (cum, 0, sizeof (*cum));
 
+  cum->call_abi = ix86_function_type_abi (fntype);
   /* Set up the number of registers to use for passing arguments.  */
   cum->nregs = ix86_regparm;
   /* Set up the number of registers to use for passing arguments.  */
   cum->nregs = ix86_regparm;
+  if (TARGET_64BIT)
+    {
+      if (cum->call_abi != DEFAULT_ABI)
+        cum->nregs = DEFAULT_ABI != SYSV_ABI ? X86_64_REGPARM_MAX
+                                            : X64_REGPARM_MAX;
+    }
   if (TARGET_SSE)
   if (TARGET_SSE)
-    cum->sse_nregs = SSE_REGPARM_MAX;
+    {
+      cum->sse_nregs = SSE_REGPARM_MAX;
+      if (TARGET_64BIT)
+        {
+          if (cum->call_abi != DEFAULT_ABI)
+            cum->sse_nregs = DEFAULT_ABI != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
+                                                    : X64_SSE_REGPARM_MAX;
+        }
+    }
   if (TARGET_MMX)
     cum->mmx_nregs = MMX_REGPARM_MAX;
   cum->warn_sse = true;
   if (TARGET_MMX)
     cum->mmx_nregs = MMX_REGPARM_MAX;
   cum->warn_sse = true;
@@ -4331,7 +4448,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
   if (type)
     mode = type_natural_mode (type);
 
   if (type)
     mode = type_natural_mode (type);
 
-  if (TARGET_64BIT_MS_ABI)
+  if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
     function_arg_advance_ms_64 (cum, bytes, words);
   else if (TARGET_64BIT)
     function_arg_advance_64 (cum, mode, type, words);
     function_arg_advance_ms_64 (cum, bytes, words);
   else if (TARGET_64BIT)
     function_arg_advance_64 (cum, mode, type, words);
@@ -4458,8 +4575,11 @@ function_arg_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
   if (mode == VOIDmode)
     return GEN_INT (cum->maybe_vaarg
                    ? (cum->sse_nregs < 0
   if (mode == VOIDmode)
     return GEN_INT (cum->maybe_vaarg
                    ? (cum->sse_nregs < 0
-                      ? SSE_REGPARM_MAX
-                      : cum->sse_regno)
+                      ? (cum->call_abi == DEFAULT_ABI
+                         ? SSE_REGPARM_MAX
+                         : (DEFAULT_ABI != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
+                                                    : X64_SSE_REGPARM_MAX))
+              : cum->sse_regno)
                    : -1);
 
   return construct_container (mode, orig_mode, type, 0, cum->nregs,
                    : -1);
 
   return construct_container (mode, orig_mode, type, 0, cum->nregs,
@@ -4533,7 +4653,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode,
   if (type && TREE_CODE (type) == VECTOR_TYPE)
     mode = type_natural_mode (type);
 
   if (type && TREE_CODE (type) == VECTOR_TYPE)
     mode = type_natural_mode (type);
 
-  if (TARGET_64BIT_MS_ABI)
+  if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
     return function_arg_ms_64 (cum, mode, omode, named, bytes);
   else if (TARGET_64BIT)
     return function_arg_64 (cum, mode, omode, type);
     return function_arg_ms_64 (cum, mode, omode, named, bytes);
   else if (TARGET_64BIT)
     return function_arg_64 (cum, mode, omode, type);
@@ -4553,7 +4673,7 @@ ix86_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
                        const_tree type, bool named ATTRIBUTE_UNUSED)
 {
   /* See Windows x64 Software Convention.  */
                        const_tree type, bool named ATTRIBUTE_UNUSED)
 {
   /* See Windows x64 Software Convention.  */
-  if (TARGET_64BIT_MS_ABI)
+  if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
     {
       int msize = (int) GET_MODE_SIZE (mode);
       if (type)
     {
       int msize = (int) GET_MODE_SIZE (mode);
       if (type)
@@ -4686,7 +4806,10 @@ ix86_function_value_regno_p (int regno)
       return true;
 
     case FIRST_FLOAT_REG:
       return true;
 
     case FIRST_FLOAT_REG:
-      if (TARGET_64BIT_MS_ABI)
+      /* TODO: The function should depend on current function ABI but
+       builtins.c would need updating then. Therefore we use the
+       default ABI.  */
+      if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)
        return false;
       return TARGET_FLOAT_RETURNS_IN_80387;
 
        return false;
       return TARGET_FLOAT_RETURNS_IN_80387;
 
@@ -4777,7 +4900,7 @@ function_value_64 (enum machine_mode orig_mode, enum machine_mode mode,
     }
 
   ret = construct_container (mode, orig_mode, valtype, 1,
     }
 
   ret = construct_container (mode, orig_mode, valtype, 1,
-                            REGPARM_MAX, SSE_REGPARM_MAX,
+                            X86_64_REGPARM_MAX, X86_64_SSE_REGPARM_MAX,
                             x86_64_int_return_registers, 0);
 
   /* For zero sized structures, construct_container returns NULL, but we
                             x86_64_int_return_registers, 0);
 
   /* For zero sized structures, construct_container returns NULL, but we
@@ -4825,7 +4948,7 @@ ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl,
     fn = fntype_or_decl;
   fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
 
     fn = fntype_or_decl;
   fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
 
-  if (TARGET_64BIT_MS_ABI)
+  if (TARGET_64BIT && ix86_function_type_abi (fntype) == MS_ABI)
     return function_value_ms_64 (orig_mode, mode);
   else if (TARGET_64BIT)
     return function_value_64 (orig_mode, mode, valtype);
     return function_value_ms_64 (orig_mode, mode);
   else if (TARGET_64BIT)
     return function_value_64 (orig_mode, mode, valtype);
@@ -5022,7 +5145,7 @@ ix86_build_builtin_va_list (void)
   tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
 
   /* For i386 we use plain pointer to argument area.  */
   tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
 
   /* For i386 we use plain pointer to argument area.  */
-  if (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
+  if (!TARGET_64BIT || ix86_cfun_abi () == MS_ABI)
     return build_pointer_type (char_type_node);
 
   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
     return build_pointer_type (char_type_node);
 
   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
@@ -5070,6 +5193,10 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
   rtx nsse_reg;
   alias_set_type set;
   int i;
   rtx nsse_reg;
   alias_set_type set;
   int i;
+  int regparm = ix86_regparm;
+
+  if((cum ? cum->call_abi : ix86_cfun_abi ()) != DEFAULT_ABI)
+    regparm = DEFAULT_ABI != SYSV_ABI ? X86_64_REGPARM_MAX : X64_REGPARM_MAX;
 
   if (! cfun->va_list_gpr_size && ! cfun->va_list_fpr_size)
     return;
 
   if (! cfun->va_list_gpr_size && ! cfun->va_list_fpr_size)
     return;
@@ -5089,7 +5216,7 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
   set = get_varargs_alias_set ();
 
   for (i = cum->regno;
   set = get_varargs_alias_set ();
 
   for (i = cum->regno;
-       i < ix86_regparm
+       i < regparm
        && i < cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
        i++)
     {
        && i < cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
        i++)
     {
@@ -5136,7 +5263,7 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
       tmp_reg = gen_reg_rtx (Pmode);
       emit_insn (gen_rtx_SET (VOIDmode, tmp_reg,
                              plus_constant (save_area,
       tmp_reg = gen_reg_rtx (Pmode);
       emit_insn (gen_rtx_SET (VOIDmode, tmp_reg,
                              plus_constant (save_area,
-                                            8 * REGPARM_MAX + 127)));
+                                            8 * X86_64_REGPARM_MAX + 127)));
       mem = gen_rtx_MEM (BLKmode, plus_constant (tmp_reg, -127));
       MEM_NOTRAP_P (mem) = 1;
       set_mem_alias_set (mem, set);
       mem = gen_rtx_MEM (BLKmode, plus_constant (tmp_reg, -127));
       MEM_NOTRAP_P (mem) = 1;
       set_mem_alias_set (mem, set);
@@ -5154,7 +5281,7 @@ setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
   alias_set_type set = get_varargs_alias_set ();
   int i;
 
   alias_set_type set = get_varargs_alias_set ();
   int i;
 
-  for (i = cum->regno; i < REGPARM_MAX; i++)
+  for (i = cum->regno; i < X64_REGPARM_MAX; i++)
     {
       rtx reg, mem;
 
     {
       rtx reg, mem;
 
@@ -5192,7 +5319,7 @@ ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
   if (stdarg_p (fntype))
     function_arg_advance (&next_cum, mode, type, 1);
 
   if (stdarg_p (fntype))
     function_arg_advance (&next_cum, mode, type, 1);
 
-  if (TARGET_64BIT_MS_ABI)
+  if ((cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
     setup_incoming_varargs_ms_64 (&next_cum);
   else
     setup_incoming_varargs_64 (&next_cum);
     setup_incoming_varargs_ms_64 (&next_cum);
   else
     setup_incoming_varargs_64 (&next_cum);
@@ -5209,7 +5336,7 @@ ix86_va_start (tree valist, rtx nextarg)
   tree type;
 
   /* Only 64bit target needs something special.  */
   tree type;
 
   /* Only 64bit target needs something special.  */
-  if (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
+  if (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI)
     {
       std_expand_builtin_va_start (valist, nextarg);
       return;
     {
       std_expand_builtin_va_start (valist, nextarg);
       return;
@@ -5244,7 +5371,7 @@ ix86_va_start (tree valist, rtx nextarg)
     {
       type = TREE_TYPE (fpr);
       t = build2 (GIMPLE_MODIFY_STMT, type, fpr,
     {
       type = TREE_TYPE (fpr);
       t = build2 (GIMPLE_MODIFY_STMT, type, fpr,
-                 build_int_cst (type, n_fpr * 16 + 8*REGPARM_MAX));
+                 build_int_cst (type, n_fpr * 16 + 8*X86_64_REGPARM_MAX));
       TREE_SIDE_EFFECTS (t) = 1;
       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
     }
       TREE_SIDE_EFFECTS (t) = 1;
       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
     }
@@ -5288,7 +5415,7 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
   enum machine_mode nat_mode;
 
   /* Only 64bit target needs something special.  */
   enum machine_mode nat_mode;
 
   /* Only 64bit target needs something special.  */
-  if (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
+  if (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI)
     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
 
   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
 
   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
@@ -5310,7 +5437,8 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
 
   nat_mode = type_natural_mode (type);
   container = construct_container (nat_mode, TYPE_MODE (type), type, 0,
 
   nat_mode = type_natural_mode (type);
   container = construct_container (nat_mode, TYPE_MODE (type), type, 0,
-                                  REGPARM_MAX, SSE_REGPARM_MAX, intreg, 0);
+                                  X86_64_REGPARM_MAX, X86_64_SSE_REGPARM_MAX,
+                                  intreg, 0);
 
   /* Pull the value out of the saved registers.  */
 
 
   /* Pull the value out of the saved registers.  */
 
@@ -5379,7 +5507,7 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
       if (needed_intregs)
        {
          t = build_int_cst (TREE_TYPE (gpr),
       if (needed_intregs)
        {
          t = build_int_cst (TREE_TYPE (gpr),
-                            (REGPARM_MAX - needed_intregs + 1) * 8);
+                            (X86_64_REGPARM_MAX - needed_intregs + 1) * 8);
          t = build2 (GE_EXPR, boolean_type_node, gpr, t);
          t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
          t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
          t = build2 (GE_EXPR, boolean_type_node, gpr, t);
          t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
          t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
@@ -5388,8 +5516,8 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
       if (needed_sseregs)
        {
          t = build_int_cst (TREE_TYPE (fpr),
       if (needed_sseregs)
        {
          t = build_int_cst (TREE_TYPE (fpr),
-                            (SSE_REGPARM_MAX - needed_sseregs + 1) * 16
-                            + REGPARM_MAX * 8);
+                            (X86_64_SSE_REGPARM_MAX - needed_sseregs + 1) * 16
+                            + X86_64_REGPARM_MAX * 8);
          t = build2 (GE_EXPR, boolean_type_node, fpr, t);
          t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
          t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
          t = build2 (GE_EXPR, boolean_type_node, fpr, t);
          t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
          t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
@@ -6515,9 +6643,9 @@ ix86_expand_prologue (void)
       bool eax_live;
       rtx t;
 
       bool eax_live;
       rtx t;
 
-      gcc_assert (!TARGET_64BIT || TARGET_64BIT_MS_ABI);
+      gcc_assert (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI);
 
 
-      if (TARGET_64BIT_MS_ABI)
+      if (cfun->machine->call_abi == MS_ABI)
        eax_live = false;
       else
        eax_live = ix86_eax_live_at_start_p ();
        eax_live = false;
       else
        eax_live = ix86_eax_live_at_start_p ();
@@ -8331,7 +8459,7 @@ output_pic_addr_const (FILE *file, rtx x, int code)
 #endif
          assemble_name (file, name);
        }
 #endif
          assemble_name (file, name);
        }
-      if (!TARGET_MACHO && !TARGET_64BIT_MS_ABI
+      if (!TARGET_MACHO && !(TARGET_64BIT && DEFAULT_ABI == MS_ABI)
          && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
        fputs ("@PLT", file);
       break;
          && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
        fputs ("@PLT", file);
       break;
@@ -16422,6 +16550,7 @@ ix86_init_machine_status (void)
   f = GGC_CNEW (struct machine_function);
   f->use_fast_prologue_epilogue_nregs = -1;
   f->tls_descriptor_call_expanded_p = 0;
   f = GGC_CNEW (struct machine_function);
   f->use_fast_prologue_epilogue_nregs = -1;
   f->tls_descriptor_call_expanded_p = 0;
+  f->call_abi = DEFAULT_ABI;
 
   return f;
 }
 
   return f;
 }
@@ -23009,7 +23138,7 @@ x86_this_parameter (tree function)
     {
       const int *parm_regs;
 
     {
       const int *parm_regs;
 
-      if (TARGET_64BIT_MS_ABI)
+      if (ix86_function_type_abi (type) == MS_ABI)
         parm_regs = x86_64_ms_abi_int_parameter_registers;
       else
         parm_regs = x86_64_int_parameter_registers;
         parm_regs = x86_64_ms_abi_int_parameter_registers;
       else
         parm_regs = x86_64_int_parameter_registers;
@@ -23177,7 +23306,7 @@ x86_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED,
        output_asm_insn ("jmp\t%P0", xops);
       /* All thunks should be in the same object as their target,
         and thus binds_local_p should be true.  */
        output_asm_insn ("jmp\t%P0", xops);
       /* All thunks should be in the same object as their target,
         and thus binds_local_p should be true.  */
-      else if (TARGET_64BIT_MS_ABI)
+      else if (TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
        gcc_unreachable ();
       else
        {
        gcc_unreachable ();
       else
        {
@@ -23259,7 +23388,7 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
       fprintf (file, "\tleaq\t%sP%d@(%%rip),%%r11\n", LPREFIX, labelno);
 #endif
 
       fprintf (file, "\tleaq\t%sP%d@(%%rip),%%r11\n", LPREFIX, labelno);
 #endif
 
-      if (!TARGET_64BIT_MS_ABI && flag_pic)
+      if (DEFAULT_ABI == SYSV_ABI && flag_pic)
        fprintf (file, "\tcall\t*%s@GOTPCREL(%%rip)\n", MCOUNT_NAME);
       else
        fprintf (file, "\tcall\t%s\n", MCOUNT_NAME);
        fprintf (file, "\tcall\t*%s@GOTPCREL(%%rip)\n", MCOUNT_NAME);
       else
        fprintf (file, "\tcall\t%s\n", MCOUNT_NAME);
index ef8da17..552515f 100644 (file)
@@ -446,7 +446,17 @@ extern tree x86_mfence;
 #define TARGET_MACHO 0
 
 /* Likewise, for the Windows 64-bit ABI.  */
 #define TARGET_MACHO 0
 
 /* Likewise, for the Windows 64-bit ABI.  */
-#define TARGET_64BIT_MS_ABI 0
+#define TARGET_64BIT_MS_ABI (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
+
+/* Available call abi.  */
+enum
+{
+  SYSV_ABI = 0,
+  MS_ABI = 1
+};
+
+/* The default abi form used by target.  */
+#define DEFAULT_ABI SYSV_ABI
 
 /* Subtargets may reset this to 1 in order to enable 96-bit long double
    with the rounding mode forced to 53 bits.  */
 
 /* Subtargets may reset this to 1 in order to enable 96-bit long double
    with the rounding mode forced to 53 bits.  */
@@ -804,7 +814,8 @@ enum target_cpu_default
 #define PARM_BOUNDARY BITS_PER_WORD
 
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
 #define PARM_BOUNDARY BITS_PER_WORD
 
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
-#define STACK_BOUNDARY BITS_PER_WORD
+#define STACK_BOUNDARY (TARGET_64BIT && DEFAULT_ABI == MS_ABI ? 128 \
+                                                              : BITS_PER_WORD)
 
 /* Boundary (in *bits*) on which the stack pointer prefers to be
    aligned; the compiler cannot rely on having this alignment.  */
 
 /* Boundary (in *bits*) on which the stack pointer prefers to be
    aligned; the compiler cannot rely on having this alignment.  */
@@ -1044,6 +1055,8 @@ enum target_cpu_default
 #define ORDER_REGS_FOR_LOCAL_ALLOC x86_order_regs_for_local_alloc ()
 
 
 #define ORDER_REGS_FOR_LOCAL_ALLOC x86_order_regs_for_local_alloc ()
 
 
+#define OVERRIDE_ABI_FORMAT(FNDECL) ix86_call_abi_override (FNDECL)
+
 /* Macro to conditionally modify fixed_regs/call_used_regs.  */
 #define CONDITIONAL_REGISTER_USAGE                                     \
 do {                                                                   \
 /* Macro to conditionally modify fixed_regs/call_used_regs.  */
 #define CONDITIONAL_REGISTER_USAGE                                     \
 do {                                                                   \
@@ -1094,7 +1107,7 @@ do {                                                                      \
        for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)         \
          reg_names[i] = "";                                            \
       }                                                                        \
        for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)         \
          reg_names[i] = "";                                            \
       }                                                                        \
-    if (TARGET_64BIT_MS_ABI)                                           \
+    if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)                         \
       {                                                                        \
         call_used_regs[4 /*RSI*/] = 0;                                  \
         call_used_regs[5 /*RDI*/] = 0;                                  \
       {                                                                        \
         call_used_regs[4 /*RSI*/] = 0;                                  \
         call_used_regs[5 /*RDI*/] = 0;                                  \
@@ -1624,7 +1637,11 @@ enum reg_class
    This space can be allocated by the caller, or be a part of the
    machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
    which.  */
    This space can be allocated by the caller, or be a part of the
    machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
    which.  */
-#define REG_PARM_STACK_SPACE(FNDECL) 0
+#define REG_PARM_STACK_SPACE(FNDECL) ix86_reg_parm_stack_space (FNDECL)
+
+#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) (ix86_function_type_abi (FNTYPE) == MS_ABI ? 1 : 0)
+
+extern unsigned int ix86_reg_parm_stack_space (const_tree);
 
 /* Value is the number of bytes of arguments automatically
    popped when returning from a subroutine call.
 
 /* Value is the number of bytes of arguments automatically
    popped when returning from a subroutine call.
@@ -1686,6 +1703,8 @@ typedef struct ix86_args {
   int maybe_vaarg;             /* true for calls to possibly vardic fncts.  */
   int float_in_sse;            /* 1 if in 32-bit mode SFmode (2 for DFmode) should
                                   be passed in SSE registers.  Otherwise 0.  */
   int maybe_vaarg;             /* true for calls to possibly vardic fncts.  */
   int float_in_sse;            /* 1 if in 32-bit mode SFmode (2 for DFmode) should
                                   be passed in SSE registers.  Otherwise 0.  */
+  int call_abi;                        /* Set to SYSV_ABI for sysv abi. Otherwise
+                                  MS_ABI for ms abi.  */
 } CUMULATIVE_ARGS;
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
 } CUMULATIVE_ARGS;
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
@@ -1953,9 +1972,22 @@ do {                                                                     \
    is also used as the pic register in ELF.  So for now, don't allow more than
    3 registers to be passed in registers.  */
 
    is also used as the pic register in ELF.  So for now, don't allow more than
    3 registers to be passed in registers.  */
 
-#define REGPARM_MAX (TARGET_64BIT ? 6 : 3)
+/* Abi specific values for REGPARM_MAX and SSE_REGPARM_MAX */
+#define X86_64_REGPARM_MAX 6
+#define X64_REGPARM_MAX 4
+#define X86_32_REGPARM_MAX 3
+
+#define X86_64_SSE_REGPARM_MAX 8
+#define X64_SSE_REGPARM_MAX 4
+#define X86_32_SSE_REGPARM_MAX (TARGET_SSE ? 3 : 0)
+
+#define REGPARM_MAX (TARGET_64BIT ? (TARGET_64BIT_MS_ABI ? X64_REGPARM_MAX \
+                                                        : X86_64_REGPARM_MAX) \
+                                 : X86_32_REGPARM_MAX)
 
 
-#define SSE_REGPARM_MAX (TARGET_64BIT ? 8 : (TARGET_SSE ? 3 : 0))
+#define SSE_REGPARM_MAX (TARGET_64BIT ? (TARGET_64BIT_MS_ABI ? X64_SSE_REGPARM_MAX \
+                                                            : X86_64_SSE_REGPARM_MAX) \
+                                     : X86_32_SSE_REGPARM_MAX)
 
 #define MMX_REGPARM_MAX (TARGET_64BIT ? 0 : (TARGET_MMX ? 3 : 0))
 
 
 #define MMX_REGPARM_MAX (TARGET_64BIT ? 0 : (TARGET_MMX ? 3 : 0))
 
@@ -2464,6 +2496,9 @@ struct machine_function GTY(())
      ix86_current_function_calls_tls_descriptor macro for a better
      approximation.  */
   int tls_descriptor_call_expanded_p;
      ix86_current_function_calls_tls_descriptor macro for a better
      approximation.  */
   int tls_descriptor_call_expanded_p;
+  /* This value is used for amd64 targets and specifies the current abi
+     to be used. MS_ABI means ms abi. Otherwise SYSV_ABI means sysv abi.  */
+  int call_abi;
 };
 
 #define ix86_stack_locals (cfun->machine->stack_locals)
 };
 
 #define ix86_stack_locals (cfun->machine->stack_locals)
index 2eec13e..ba438fe 100644 (file)
 
   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
                     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
 
   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
                     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
-                   operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
+                   operands[0], const0_rtx,
+                   GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
+                                                     : X64_SSE_REGPARM_MAX)
+                            - 1),
                    NULL, 0);
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
                    NULL, 0);
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
    (use (match_operand:DI 2 "const_int_operand" "i"))
    (use (label_ref:DI (match_operand 3 "" "X")))]
   "TARGET_64BIT
    (use (match_operand:DI 2 "const_int_operand" "i"))
    (use (label_ref:DI (match_operand 3 "" "X")))]
   "TARGET_64BIT
-   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
+   && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
 {
   int i;
   operands[0] = gen_rtx_MEM (Pmode,
                             gen_rtx_PLUS (Pmode, operands[0], operands[4]));
   output_asm_insn ("jmp\t%A1", operands);
    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
 {
   int i;
   operands[0] = gen_rtx_MEM (Pmode,
                             gen_rtx_PLUS (Pmode, operands[0], operands[4]));
   output_asm_insn ("jmp\t%A1", operands);
-  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
+  for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
     {
       operands[4] = adjust_address (operands[0], DImode, i*16);
       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
     {
       operands[4] = adjust_address (operands[0], DImode, i*16);
       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
index 3a3b74c..7628896 100644 (file)
@@ -38,7 +38,7 @@ along with GCC; see the file COPYING3.  If not see
       builtin_define_std ("WINNT");                            \
       builtin_define_with_int_value ("_INTEGRAL_MAX_BITS",     \
                                     TYPE_PRECISION (intmax_type_node));\
       builtin_define_std ("WINNT");                            \
       builtin_define_with_int_value ("_INTEGRAL_MAX_BITS",     \
                                     TYPE_PRECISION (intmax_type_node));\
-      if (TARGET_64BIT_MS_ABI)                                 \
+      if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)                       \
        {                                                       \
          builtin_define ("__MINGW64__");                       \
          builtin_define_std ("WIN64");                         \
        {                                                       \
          builtin_define ("__MINGW64__");                       \
          builtin_define_std ("WIN64");                         \
index 103af2c..9c02560 100644 (file)
@@ -2508,6 +2508,19 @@ instruction).  Caveat: such addressing is by definition not position
 independent and hence this attribute must not be used for objects
 defined by shared libraries.
 
 independent and hence this attribute must not be used for objects
 defined by shared libraries.
 
+@item ms_abi/sysv_abi
+@cindex @code[ms_abi} attribute
+@cindex @code{sysv_abi} attribute
+
+On 64-bit x86_65-*-* targets, you can use an ABI attribute to indicate
+which calling convention should be used for a function.  The @code{ms_abi}
+attribute tells the compiler to use the Microsoft ABI, while the
+@code{sysv_abi} attribute tells the compiler to use the ABI used on
+GNU/Linux and other systems.  The default is to use the Microsoft ABI
+when targeting Windows.  On all other systems, the default is the AMD ABI.
+
+Note, This feature is currently sorried out for Windows targets trying to
+
 @item naked
 @cindex function without a prologue/epilogue code
 Use this attribute on the ARM, AVR, IP2K and SPU ports to indicate that
 @item naked
 @cindex function without a prologue/epilogue code
 Use this attribute on the ARM, AVR, IP2K and SPU ports to indicate that
index 3e4d2b7..d18bf2e 100644 (file)
@@ -4055,6 +4055,15 @@ arguments are passed on the stack, there is no need to store anything in
 should not be empty, so use @code{int}.
 @end defmac
 
 should not be empty, so use @code{int}.
 @end defmac
 
+@defmac OVERRIDE_ABI_FORMAT (@var{fndecl})
+If defined, this macro is called before generating any code for a
+function, but after the @var{cfun} descriptor for the function has been
+created.  The back end may use this macro to update @var{cfun} to
+reflect an ABI other than that which would normally be used by default.
+If the compiler is generating code for a compiler-generated function,
+@var{fndecl} may be @code{NULL}.
+@end defmac
+
 @defmac INIT_CUMULATIVE_ARGS (@var{cum}, @var{fntype}, @var{libname}, @var{fndecl}, @var{n_named_args})
 A C statement (sans semicolon) for initializing the variable
 @var{cum} for the state at the beginning of the argument list.  The
 @defmac INIT_CUMULATIVE_ARGS (@var{cum}, @var{fntype}, @var{libname}, @var{fndecl}, @var{n_named_args})
 A C statement (sans semicolon) for initializing the variable
 @var{cum} for the state at the beginning of the argument list.  The
index bb4a2e6..30dd9f3 100644 (file)
@@ -3852,6 +3852,10 @@ allocate_struct_function (tree fndecl, bool abstract_p)
   if (init_machine_status)
     cfun->machine = (*init_machine_status) ();
 
   if (init_machine_status)
     cfun->machine = (*init_machine_status) ();
 
+#ifdef OVERRIDE_ABI_FORMAT
+  OVERRIDE_ABI_FORMAT (fndecl);
+#endif
+
   if (fndecl != NULL_TREE)
     {
       DECL_STRUCT_FUNCTION (fndecl) = cfun;
   if (fndecl != NULL_TREE)
     {
       DECL_STRUCT_FUNCTION (fndecl) = cfun;
index 19e882f..69b6169 100644 (file)
 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false
 
 #define TARGET_STRUCT_VALUE_RTX hook_rtx_tree_int_null
 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false
 
 #define TARGET_STRUCT_VALUE_RTX hook_rtx_tree_int_null
-#ifndef TARGET_RETURN_IN_MEMORY
 #define TARGET_RETURN_IN_MEMORY default_return_in_memory
 #define TARGET_RETURN_IN_MEMORY default_return_in_memory
-#endif
 #define TARGET_RETURN_IN_MSB hook_bool_const_tree_false
 
 #define TARGET_EXPAND_BUILTIN_SAVEREGS default_expand_builtin_saveregs
 #define TARGET_RETURN_IN_MSB hook_bool_const_tree_false
 
 #define TARGET_EXPAND_BUILTIN_SAVEREGS default_expand_builtin_saveregs