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
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
-#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)                         \
@@ -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 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 */
@@ -214,7 +205,7 @@ do {                                                \
 #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.
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 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);
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.  */
-#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.  */
 
@@ -2306,11 +2306,11 @@ override_options (void)
     }
   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.  */
-      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;
@@ -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)
-     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
@@ -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_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;
@@ -3269,7 +3270,11 @@ ix86_function_regparm (const_tree type, const_tree decl)
   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)
@@ -3500,15 +3505,20 @@ ix86_function_arg_regno_p (int regno)
         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.  */
-  if (!TARGET_64BIT_MS_ABI && regno == AX_REG)
+  if (DEFAULT_ABI == SYSV_ABI && regno == AX_REG)
     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;
-  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;
@@ -3529,6 +3539,98 @@ ix86_must_pass_in_stack (enum machine_mode mode, const_tree 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.  */
@@ -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));
 
+  cum->call_abi = ix86_function_type_abi (fntype);
   /* 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)
-    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;
@@ -4331,7 +4448,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
   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);
@@ -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
-                      ? 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,
@@ -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 (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);
@@ -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.  */
-  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)
@@ -4686,7 +4806,10 @@ ix86_function_value_regno_p (int regno)
       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;
 
@@ -4777,7 +4900,7 @@ function_value_64 (enum machine_mode orig_mode, enum machine_mode mode,
     }
 
   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
@@ -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;
 
-  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);
@@ -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.  */
-  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);
@@ -5070,6 +5193,10 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
   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;
@@ -5089,7 +5216,7 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
   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++)
     {
@@ -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,
-                                            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);
@@ -5154,7 +5281,7 @@ setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
   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;
 
@@ -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 (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);
@@ -5209,7 +5336,7 @@ ix86_va_start (tree valist, rtx nextarg)
   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;
@@ -5244,7 +5371,7 @@ ix86_va_start (tree valist, rtx nextarg)
     {
       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);
     }
@@ -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.  */
-  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));
@@ -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,
-                                  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.  */
 
@@ -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),
-                            (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);
@@ -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),
-                            (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);
@@ -6515,9 +6643,9 @@ ix86_expand_prologue (void)
       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 ();
@@ -8331,7 +8459,7 @@ output_pic_addr_const (FILE *file, rtx x, int code)
 #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;
@@ -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->call_abi = DEFAULT_ABI;
 
   return f;
 }
@@ -23009,7 +23138,7 @@ x86_this_parameter (tree function)
     {
       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;
@@ -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.  */
-      else if (TARGET_64BIT_MS_ABI)
+      else if (TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
        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
 
-      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);
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_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.  */
@@ -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 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.  */
@@ -1044,6 +1055,8 @@ enum target_cpu_default
 #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 {                                                                   \
@@ -1094,7 +1107,7 @@ do {                                                                      \
        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;                                  \
@@ -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.  */
-#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.
@@ -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 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
@@ -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.  */
 
-#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))
 
@@ -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;
+  /* 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)
index 2eec13e..ba438fe 100644 (file)
 
   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++)
    (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);
-  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));
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));\
-      if (TARGET_64BIT_MS_ABI)                                 \
+      if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)                       \
        {                                                       \
          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.
 
+@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
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
 
+@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
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) ();
 
+#ifdef OVERRIDE_ABI_FORMAT
+  OVERRIDE_ABI_FORMAT (fndecl);
+#endif
+
   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
-#ifndef TARGET_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