OSDN Git Service

gcc/
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Mar 2009 22:22:30 +0000 (22:22 +0000)
committerhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Mar 2009 22:22:30 +0000 (22:22 +0000)
2009-03-27  H.J. Lu  <hongjiu.lu@intel.com>

PR target/39472
* config/i386/i386.c (ix86_abi): New.
(override_options): Handle -mabi=.
(ix86_function_arg_regno_p): Replace DEFAULT_ABI with
ix86_abi.
(ix86_call_abi_override): Likewise.
(init_cumulative_args): Likewise.
(function_arg_advance): Likewise.
(function_arg_64): Likewise.
(function_arg): Likewise.
(ix86_pass_by_reference): Likewise.
(ix86_function_value_regno_p): Likewise.
(ix86_build_builtin_va_list_abi): Likewise.
(setup_incoming_varargs_64): Likewise.
(is_va_list_char_pointer): Likewise.
(ix86_init_machine_status): Likewise.
(ix86_reg_parm_stack_space): Use enum calling_abi on
call_abi.
(ix86_function_type_abi): Return enum calling_abi.  Rewrite
for 64bit.  Replace DEFAULT_ABI with ix86_abi.
(ix86_function_abi): Make it static and return enum
calling_abi.
(ix86_cfun_abi): Return enum calling_abi.  Replace DEFAULT_ABI
with ix86_abi.
(ix86_fn_abi_va_list): Updated.

* config/i386/i386.h (ix86_abi): New.
(STACK_BOUNDARY): Replace DEFAULT_ABI with ix86_abi.
(CONDITIONAL_REGISTER_USAGE): Likewise.
(CUMULATIVE_ARGS): Change call_abi type to enum calling_abi.
(machine_function): Likewise.

* config/i386/i386.md (untyped_call): Replace DEFAULT_ABI
with ix86_abi.
* config/i386/cygming.h (TARGET_64BIT_MS_ABI): Likewise.
(STACK_BOUNDARY): Likewise.
* config/i386/mingw32.h (EXTRA_OS_CPP_BUILTINS): Likewise.

* config/i386/i386.opt (mabi=): New.

* config/i386/i386-protos.h (ix86_cfun_abi): Changed to
return enum calling_abi.
(ix86_function_type_abi): Likewise.
(ix86_function_abi): Removed.

* doc/invoke.texi: Document -mabi= option for x86.

gcc/testsuite/

2009-03-27  H.J. Lu  <hongjiu.lu@intel.com>

PR target/39472
* gcc.target/x86_64/abi/callabi/func-2a.c: New.
* gcc.target/x86_64/abi/callabi/func-2b.c: Likewise.
* gcc.target/x86_64/abi/callabi/func-indirect-2a.c: Likewise.
* gcc.target/x86_64/abi/callabi/func-indirect-2b.c: Likewise.
* gcc.target/x86_64/abi/callabi/vaarg-4a.c: Likewise.
* gcc.target/x86_64/abi/callabi/vaarg-4b.c: Likewise.
* gcc.target/x86_64/abi/callabi/vaarg-5a.c: Likewise.
* gcc.target/x86_64/abi/callabi/vaarg-5b.c: Likewise.

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

18 files changed:
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/i386.opt
gcc/config/i386/mingw32.h
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5b.c [new file with mode: 0644]

index 3c58c26..d874d24 100644 (file)
@@ -1,3 +1,52 @@
+2009-03-27  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/39472
+       * config/i386/i386.c (ix86_abi): New.
+       (override_options): Handle -mabi=.
+       (ix86_function_arg_regno_p): Replace DEFAULT_ABI with
+       ix86_abi.
+       (ix86_call_abi_override): Likewise.
+       (init_cumulative_args): Likewise.
+       (function_arg_advance): Likewise.
+       (function_arg_64): Likewise.
+       (function_arg): Likewise.
+       (ix86_pass_by_reference): Likewise.
+       (ix86_function_value_regno_p): Likewise.
+       (ix86_build_builtin_va_list_abi): Likewise.
+       (setup_incoming_varargs_64): Likewise.
+       (is_va_list_char_pointer): Likewise.
+       (ix86_init_machine_status): Likewise.
+       (ix86_reg_parm_stack_space): Use enum calling_abi on
+       call_abi.
+       (ix86_function_type_abi): Return enum calling_abi.  Rewrite
+       for 64bit.  Replace DEFAULT_ABI with ix86_abi.
+       (ix86_function_abi): Make it static and return enum
+       calling_abi.
+       (ix86_cfun_abi): Return enum calling_abi.  Replace DEFAULT_ABI
+       with ix86_abi.
+       (ix86_fn_abi_va_list): Updated.
+
+       * config/i386/i386.h (ix86_abi): New.
+       (STACK_BOUNDARY): Replace DEFAULT_ABI with ix86_abi.
+       (CONDITIONAL_REGISTER_USAGE): Likewise.
+       (CUMULATIVE_ARGS): Change call_abi type to enum calling_abi.
+       (machine_function): Likewise.
+
+       * config/i386/i386.md (untyped_call): Replace DEFAULT_ABI
+       with ix86_abi.
+       * config/i386/cygming.h (TARGET_64BIT_MS_ABI): Likewise.
+       (STACK_BOUNDARY): Likewise.
+       * config/i386/mingw32.h (EXTRA_OS_CPP_BUILTINS): Likewise.
+
+       * config/i386/i386.opt (mabi=): New.
+
+       * config/i386/i386-protos.h (ix86_cfun_abi): Changed to
+       return enum calling_abi.
+       (ix86_function_type_abi): Likewise.
+       (ix86_function_abi): Removed.
+
+       * doc/invoke.texi: Document -mabi= option for x86.
+
 2009-03-27  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * builtins.c (real_dconstp): Delete.
index db43ffd..431e926 100644 (file)
@@ -34,7 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #endif
 
 #undef TARGET_64BIT_MS_ABI
-#define TARGET_64BIT_MS_ABI (!cfun ? DEFAULT_ABI == MS_ABI : TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
+#define TARGET_64BIT_MS_ABI (!cfun ? ix86_abi == MS_ABI : TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
 
 #undef DEFAULT_ABI
 #define DEFAULT_ABI (TARGET_64BIT ? MS_ABI : SYSV_ABI)
@@ -202,7 +202,7 @@ do {                                                \
 #define CHECK_STACK_LIMIT 4000
 
 #undef STACK_BOUNDARY
-#define STACK_BOUNDARY (DEFAULT_ABI == MS_ABI ? 128 : BITS_PER_WORD)
+#define STACK_BOUNDARY (ix86_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 23936a8..d6f5e5a 100644 (file)
@@ -139,9 +139,8 @@ 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 enum calling_abi ix86_cfun_abi (void);
+extern enum calling_abi ix86_function_type_abi (const_tree);
 extern void ix86_call_abi_override (const_tree);
 extern tree ix86_fn_abi_va_list (tree);
 extern tree ix86_canonical_va_list_type (tree);
index 18063e6..5f36ec3 100644 (file)
@@ -1743,6 +1743,9 @@ static unsigned int ix86_default_incoming_stack_boundary;
 /* Alignment for incoming stack boundary in bits.  */
 unsigned int ix86_incoming_stack_boundary;
 
+/* The abi used by target.  */
+enum calling_abi ix86_abi = DEFAULT_ABI;
+
 /* Values 1-5: see jump.c */
 int ix86_branch_cost;
 
@@ -1819,6 +1822,8 @@ static bool ix86_valid_target_attribute_inner_p (tree, char *[]);
 static bool ix86_can_inline_p (tree, tree);
 static void ix86_set_current_function (tree);
 
+static enum calling_abi ix86_function_abi (const_tree);
+
 \f
 /* The svr4 ABI for the i386 says that records and unions are returned
    in memory.  */
@@ -2716,6 +2721,18 @@ override_options (bool main_args_p)
     error ("bad value (%s) for %sarch=%s %s",
           ix86_arch_string, prefix, suffix, sw);
 
+  /* Validate -mabi= value.  */
+  if (ix86_abi_string)
+    {
+      if (strcmp (ix86_abi_string, "sysv") == 0)
+       ix86_abi = SYSV_ABI;
+      else if (strcmp (ix86_abi_string, "ms") == 0)
+       ix86_abi = MS_ABI;
+      else
+       error ("unknown ABI (%s) for %sabi=%s %s",
+              ix86_abi_string, prefix, suffix, sw);
+    }
+
   if (ix86_cmodel_string != 0)
     {
       if (!strcmp (ix86_cmodel_string, "small"))
@@ -4515,14 +4532,14 @@ ix86_function_arg_regno_p (int regno)
      default ABI.  */
 
   /* RAX is used as hidden argument to va_arg functions.  */
-  if (DEFAULT_ABI == SYSV_ABI && regno == AX_REG)
+  if (ix86_abi == SYSV_ABI && regno == AX_REG)
     return true;
 
-  if (DEFAULT_ABI == MS_ABI)
+  if (ix86_abi == MS_ABI)
     parm_regs = x86_64_ms_abi_int_parameter_registers;
   else
     parm_regs = x86_64_int_parameter_registers;
-  for (i = 0; i < (DEFAULT_ABI == MS_ABI ? X64_REGPARM_MAX
+  for (i = 0; i < (ix86_abi == MS_ABI ? X64_REGPARM_MAX
                                         : X86_64_REGPARM_MAX); i++)
     if (regno == parm_regs[i])
       return true;
@@ -4550,7 +4567,7 @@ ix86_must_pass_in_stack (enum machine_mode mode, const_tree type)
 int
 ix86_reg_parm_stack_space (const_tree fndecl)
 {
-  int call_abi = SYSV_ABI;
+  enum calling_abi call_abi = SYSV_ABI;
   if (fndecl != NULL_TREE && TREE_CODE (fndecl) == FUNCTION_DECL)
     call_abi = ix86_function_abi (fndecl);
   else
@@ -4562,37 +4579,39 @@ ix86_reg_parm_stack_space (const_tree fndecl)
 
 /* Returns value SYSV_ABI, MS_ABI dependent on fntype, specifying the
    call abi used.  */
-int
+enum calling_abi
 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;
-
+      enum calling_abi abi = ix86_abi;
+      if (abi == SYSV_ABI)
+       {
+         if (lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)))
+           abi = MS_ABI;
+       }
+      else if (lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
+       abi = SYSV_ABI;
       return abi;
     }
-  return DEFAULT_ABI;
+  return ix86_abi;
 }
 
-int
+static enum calling_abi
 ix86_function_abi (const_tree fndecl)
 {
   if (! fndecl)
-    return DEFAULT_ABI;
+    return ix86_abi;
   return ix86_function_type_abi (TREE_TYPE (fndecl));
 }
 
 /* Returns value SYSV_ABI, MS_ABI dependent on cfun, specifying the
    call abi used.  */
-int
+enum calling_abi
 ix86_cfun_abi (void)
 {
   if (! cfun || ! TARGET_64BIT)
-    return DEFAULT_ABI;
+    return ix86_abi;
   return cfun->machine->call_abi;
 }
 
@@ -4606,7 +4625,7 @@ void
 ix86_call_abi_override (const_tree fndecl)
 {
   if (fndecl == NULL_TREE)
-    cfun->machine->call_abi = DEFAULT_ABI;
+    cfun->machine->call_abi = ix86_abi;
   else
     cfun->machine->call_abi = ix86_function_type_abi (TREE_TYPE (fndecl));
 }
@@ -4646,8 +4665,8 @@ init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
   cum->nregs = ix86_regparm;
   if (TARGET_64BIT)
     {
-      if (cum->call_abi != DEFAULT_ABI)
-        cum->nregs = DEFAULT_ABI != SYSV_ABI ? X86_64_REGPARM_MAX
+      if (cum->call_abi != ix86_abi)
+        cum->nregs = ix86_abi != SYSV_ABI ? X86_64_REGPARM_MAX
                                             : X64_REGPARM_MAX;
     }
   if (TARGET_SSE)
@@ -4655,8 +4674,8 @@ init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
       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
+          if (cum->call_abi != ix86_abi)
+            cum->sse_nregs = ix86_abi != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
                                                     : X64_SSE_REGPARM_MAX;
         }
     }
@@ -5582,7 +5601,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
   if (type)
     mode = type_natural_mode (type, NULL);
 
-  if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
+  if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
     function_arg_advance_ms_64 (cum, bytes, words);
   else if (TARGET_64BIT)
     function_arg_advance_64 (cum, mode, type, words, named);
@@ -5728,9 +5747,9 @@ function_arg_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
   if (mode == VOIDmode)
     return GEN_INT (cum->maybe_vaarg
                    ? (cum->sse_nregs < 0
-                      ? (cum->call_abi == DEFAULT_ABI
+                      ? (cum->call_abi == ix86_abi
                          ? SSE_REGPARM_MAX
-                         : (DEFAULT_ABI != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
+                         : (ix86_abi != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
                                                     : X64_SSE_REGPARM_MAX))
               : cum->sse_regno)
                    : -1);
@@ -5824,7 +5843,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode,
   if (type && TREE_CODE (type) == VECTOR_TYPE)
     mode = type_natural_mode (type, cum);
 
-  if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
+  if (TARGET_64BIT && (cum ? cum->call_abi : ix86_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, named);
@@ -5844,7 +5863,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 && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
+  if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
     {
       int msize = (int) GET_MODE_SIZE (mode);
       if (type)
@@ -5984,7 +6003,7 @@ ix86_function_value_regno_p (int regno)
       /* 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)
+      if (TARGET_64BIT && ix86_abi == MS_ABI)
        return false;
       return TARGET_FLOAT_RETURNS_IN_80387;
 
@@ -6380,13 +6399,13 @@ ix86_build_builtin_va_list_abi (enum calling_abi abi)
 static tree
 ix86_build_builtin_va_list (void)
 {
-  tree ret = ix86_build_builtin_va_list_abi (DEFAULT_ABI);
+  tree ret = ix86_build_builtin_va_list_abi (ix86_abi);
 
   /* Initialize abi specific va_list builtin types.  */
   if (TARGET_64BIT)
     {
       tree t;
-      if (DEFAULT_ABI == MS_ABI)
+      if (ix86_abi == MS_ABI)
         {
           t = ix86_build_builtin_va_list_abi (SYSV_ABI);
           if (TREE_CODE (t) != RECORD_TYPE)
@@ -6400,7 +6419,7 @@ ix86_build_builtin_va_list (void)
             t = build_variant_type_copy (t);
           sysv_va_list_type_node = t;
         }
-      if (DEFAULT_ABI != MS_ABI)
+      if (ix86_abi != MS_ABI)
         {
           t = ix86_build_builtin_va_list_abi (MS_ABI);
           if (TREE_CODE (t) != RECORD_TYPE)
@@ -6433,8 +6452,8 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
   int i;
   int regparm = ix86_regparm;
 
-  if (cum->call_abi != DEFAULT_ABI)
-    regparm = DEFAULT_ABI != SYSV_ABI ? X86_64_REGPARM_MAX : X64_REGPARM_MAX;
+  if (cum->call_abi != ix86_abi)
+    regparm = ix86_abi != SYSV_ABI ? X86_64_REGPARM_MAX : X64_REGPARM_MAX;
 
   /* GPR size of varargs save area.  */
   if (cfun->va_list_gpr_size)
@@ -6587,7 +6606,7 @@ is_va_list_char_pointer (tree type)
     return true;
   canonic = ix86_canonical_va_list_type (type);
   return (canonic == ms_va_list_type_node
-          || (DEFAULT_ABI == MS_ABI && canonic == va_list_type_node));
+          || (ix86_abi == MS_ABI && canonic == va_list_type_node));
 }
 
 /* Implement va_start.  */
@@ -18724,7 +18743,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;
+  f->call_abi = ix86_abi;
 
   return f;
 }
@@ -29443,14 +29462,11 @@ x86_builtin_vectorization_cost (bool runtime_test)
 tree
 ix86_fn_abi_va_list (tree fndecl)
 {
-  int abi;
-
   if (!TARGET_64BIT)
     return va_list_type_node;
   gcc_assert (fndecl != NULL_TREE);
-  abi = ix86_function_abi ((const_tree) fndecl);
 
-  if (abi == MS_ABI)
+  if (ix86_function_abi ((const_tree) fndecl) == MS_ABI)
     return ms_va_list_type_node;
   else
     return sysv_va_list_type_node;
index 8035e84..e4d4463 100644 (file)
@@ -465,7 +465,10 @@ enum calling_abi
   MS_ABI = 1
 };
 
-/* The default abi form used by target.  */
+/* The abi used by target.  */
+extern enum calling_abi ix86_abi;
+
+/* The default abi used by target.  */
 #define DEFAULT_ABI SYSV_ABI
 
 /* Subtargets may reset this to 1 in order to enable 96-bit long double
@@ -653,7 +656,7 @@ enum target_cpu_default
 
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
 #define STACK_BOUNDARY \
- (TARGET_64BIT && DEFAULT_ABI == MS_ABI ? 128 : BITS_PER_WORD)
+ (TARGET_64BIT && ix86_abi == MS_ABI ? 128 : BITS_PER_WORD)
 
 /* Stack boundary of the main function guaranteed by OS.  */
 #define MAIN_STACK_BOUNDARY (TARGET_64BIT ? 128 : 32)
@@ -949,7 +952,7 @@ do {                                                                        \
       fixed_regs[j] = call_used_regs[j] = 1;                           \
     if (TARGET_64BIT                                                   \
        && ((cfun && cfun->machine->call_abi == MS_ABI)                 \
-           || (!cfun && DEFAULT_ABI == MS_ABI)))                       \
+           || (!cfun && ix86_abi == MS_ABI)))                          \
       {                                                                        \
        call_used_regs[SI_REG] = 0;                                     \
        call_used_regs[DI_REG] = 0;                                     \
@@ -1609,7 +1612,7 @@ 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
+  enum calling_abi call_abi;   /* Set to SYSV_ABI for sysv abi. Otherwise
                                   MS_ABI for ms abi.  */
 } CUMULATIVE_ARGS;
 
@@ -2428,7 +2431,7 @@ struct machine_function GTY(())
   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;
+   enum calling_abi call_abi;
 };
 
 #define ix86_stack_locals (cfun->machine->stack_locals)
index 39e62fb..a112198 100644 (file)
                     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
                    operands[0], const0_rtx,
                    GEN_INT ((TARGET_64BIT
-                             ? (DEFAULT_ABI == SYSV_ABI
+                             ? (ix86_abi == SYSV_ABI
                                 ? X86_64_SSE_REGPARM_MAX
                                 : X64_SSE_REGPARM_MAX)
                              : X86_32_SSE_REGPARM_MAX)
index 8530590..6fd218f 100644 (file)
@@ -228,6 +228,10 @@ mtune=
 Target RejectNegative Joined Var(ix86_tune_string)
 Schedule code for given CPU
 
+mabi=
+Target RejectNegative Joined Var(ix86_abi_string)
+Generate code that conforms to the given ABI
+
 mveclibabi=
 Target RejectNegative Joined Var(ix86_veclibabi_string)
 Vector library ABI to use
index f3fbe8c..746d7d1 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 && DEFAULT_ABI == MS_ABI)                       \
+      if (TARGET_64BIT && ix86_abi == MS_ABI)                  \
        {                                                       \
          builtin_define ("__MINGW64__");                       \
          builtin_define_std ("WIN64");                         \
index 1d58f06..ac5b2c8 100644 (file)
@@ -585,7 +585,7 @@ Objective-C and Objective-C++ Dialects}.
 -m96bit-long-double  -mregparm=@var{num}  -msseregparm @gol
 -mveclibabi=@var{type} -mpc32 -mpc64 -mpc80 -mstackrealign @gol
 -momit-leaf-frame-pointer  -mno-red-zone -mno-tls-direct-seg-refs @gol
--mcmodel=@var{code-model} @gol
+-mcmodel=@var{code-model} -mabi=@var{name} @gol
 -m32  -m64 -mlarge-data-threshold=@var{num} @gol
 -mfused-madd -mno-fused-madd -msse2avx}
 
@@ -11393,6 +11393,16 @@ when @option{-mveclibabi=acml} is used. Both @option{-ftree-vectorize} and
 @option{-funsafe-math-optimizations} have to be enabled. A SVML or ACML ABI
 compatible library will have to be specified at link time.
 
+@item -mabi=@var{name}
+@opindex mabi
+Generate code for the specified calling convention.  Permissible values
+are: @samp{sysv} for the ABI used on GNU/Linux and other systems and
+@samp{ms} for the Microsoft ABI.  The default is to use the Microsoft
+ABI when targeting Windows.  On all other systems, the default is the
+SYSV ABI.  You can control this behavior for a specific function by
+using the function attribute @samp{ms_abi}/@samp{sysv_abi}.
+@xref{Function Attributes}.
+
 @item -mpush-args
 @itemx -mno-push-args
 @opindex mpush-args
index 2f1903a..a67ad29 100644 (file)
@@ -1,3 +1,15 @@
+2009-03-27  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/39472
+       * gcc.target/x86_64/abi/callabi/func-2a.c: New.
+       * gcc.target/x86_64/abi/callabi/func-2b.c: Likewise.
+       * gcc.target/x86_64/abi/callabi/func-indirect-2a.c: Likewise.
+       * gcc.target/x86_64/abi/callabi/func-indirect-2b.c: Likewise.
+       * gcc.target/x86_64/abi/callabi/vaarg-4a.c: Likewise.
+       * gcc.target/x86_64/abi/callabi/vaarg-4b.c: Likewise.
+       * gcc.target/x86_64/abi/callabi/vaarg-5a.c: Likewise.
+       * gcc.target/x86_64/abi/callabi/vaarg-5b.c: Likewise.
+
 2009-03-27  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * gcc.dg/torture/builtin-explog-1.c: Remove tests that aren't true
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2a.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2a.c
new file mode 100644 (file)
index 0000000..048da6e
--- /dev/null
@@ -0,0 +1,27 @@
+/* Test for cross x86_64<->w64 abi standard calls.  */
+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
+/* { dg-options "-O2 -mabi=ms -std=gnu99 -ffast-math -fno-builtin" } */
+/* { dg-additional-sources "func-2b.c" } */
+
+extern void __attribute__ ((sysv_abi)) abort (void);
+long double func_cross (long double, double, float, long, int, char);
+
+long double __attribute__ ((sysv_abi))
+func_native (long double a, double b, float c, long d, int e, char f)
+{
+  long double ret;
+  ret = a + (long double) b + (long double) c;
+  ret *= (long double) (d + (long) e);
+  if (f>0)
+    ret += func_native (a,b,c,d,e,-f);
+  return ret;
+}
+
+int __attribute__ ((sysv_abi))
+main ()
+{
+  if (func_cross (1.0,2.0,3.0,1,2,3)
+      != func_native (1.0,2.0,3.0,1,2,3))
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2b.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2b.c
new file mode 100644 (file)
index 0000000..fe85dd1
--- /dev/null
@@ -0,0 +1,13 @@
+/* Test for cross x86_64<->w64 abi standard calls.  */
+/* { dg-options "-mabi=ms -std=gnu99 -ffast-math -fno-builtin" } */
+
+long double func_cross (long double a, double b, float c, long d, int e,
+                       char f)
+{
+  long double ret;
+  ret = a + (long double) b + (long double) c;
+  ret *= (long double) (d + (long) e);
+  if (f>0)
+    ret += func_cross (a,b,c,d,e,-f);
+  return ret;
+}
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2a.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2a.c
new file mode 100644 (file)
index 0000000..730b8db
--- /dev/null
@@ -0,0 +1,17 @@
+/* Test for cross x86_64<->w64 abi standard calls via variable.  */
+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
+/* { dg-options "-O2 -mabi=ms -std=gnu99 -ffast-math -fno-builtin" } */
+/* { dg-additional-sources "func-indirect-2b.c" } */
+
+extern void __attribute__ ((sysv_abi)) abort (void);
+typedef int (*func)(void *, char *, char *, short, long long);
+extern func get_callback (void);
+
+int __attribute__ ((sysv_abi))
+main ()
+{
+  func callme = get_callback ();
+  if (callme (0, 0, 0, 0x1234, 0x1234567890abcdefLL))
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2b.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2b.c
new file mode 100644 (file)
index 0000000..1a9fccd
--- /dev/null
@@ -0,0 +1,24 @@
+/* Test for cross x86_64<->w64 abi standard calls via variable.  */
+/* { dg-options "-O2 -mabi=ms -std=gnu99 -ffast-math -fno-builtin" } */
+
+typedef int (*func)(void *, char *, char *, short, long long);
+
+static int
+callback (void *ptr, char *string1, char *string2, short number,
+         long long rand)
+{
+  if (ptr != 0
+      || string1 != 0
+      || string2 != 0
+      || number != 0x1234
+      || rand != 0x1234567890abcdefLL)
+    return 1;
+  else
+    return 0;
+}
+
+func
+get_callback (void)
+{
+  return callback;
+}
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4a.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4a.c
new file mode 100644 (file)
index 0000000..a444704
--- /dev/null
@@ -0,0 +1,24 @@
+/* Test for cross x86_64<->w64 abi va_list calls.  */
+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
+/* { dg-options "-O2 -mabi=ms -std=gnu99 -fno-builtin" } */
+/* { dg-additional-sources "vaarg-4b.c" } */
+
+extern __SIZE_TYPE__ __attribute__ ((sysv_abi)) strlen (const char *);
+extern int __attribute__ ((sysv_abi)) sprintf (char *,const char *, ...);
+extern void __attribute__ ((sysv_abi)) abort (void);
+
+extern void do_cpy (char *, ...);
+
+int __attribute__ ((sysv_abi))
+main ()
+{
+  char s[256];
+
+  do_cpy (s, "1","2","3","4", "5", "6", "7", "");
+
+  if (s[0] != '1' || s[1] !='2' || s[2] != '3' || s[3] != '4'
+      || s[4] != '5' || s[5] != '6' || s[6] != '7' || s[7] != 0)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4b.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4b.c
new file mode 100644 (file)
index 0000000..f33906b
--- /dev/null
@@ -0,0 +1,31 @@
+/* Test for cross x86_64<->w64 abi va_list calls.  */
+/* { dg-options "-O2 -mabi=ms -std=gnu99 -fno-builtin" } */
+
+#include <stdarg.h>
+
+extern __SIZE_TYPE__ __attribute__ ((sysv_abi)) strlen (const char *);
+extern int __attribute__ ((sysv_abi)) sprintf (char *, const char *, ...);
+
+static void
+vdo_cpy (char *s, va_list argp)
+{
+  __SIZE_TYPE__ len;
+  char *r = s;
+  char *e;
+  *r = 0;
+  for (;;) {
+    e = va_arg (argp, char *);
+    if (*e == 0) break;
+    sprintf (r,"%s", e);
+    r += strlen (r);
+  }
+}
+
+void
+do_cpy (char *s, ...)
+{
+  va_list argp;
+  va_start (argp, s);
+  vdo_cpy (s, argp);
+  va_end (argp);
+}
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5a.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5a.c
new file mode 100644 (file)
index 0000000..e991295
--- /dev/null
@@ -0,0 +1,17 @@
+/* Test for cross x86_64<->w64 abi va_list calls.  */
+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
+/* { dg-options "-O2 -mabi=ms -std=gnu99 -fno-builtin" } */
+/* { dg-additional-sources "vaarg-5b.c" } */
+
+extern void __attribute__ ((sysv_abi)) abort (void);
+extern int fct2 (int, ...);
+
+#define SZ_ARGS        1ll,2ll,3ll,4ll,5ll,6ll,7ll,0ll
+
+int __attribute__ ((sysv_abi))
+main()
+{
+  if (fct2 (-1, SZ_ARGS) != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5b.c b/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5b.c
new file mode 100644 (file)
index 0000000..e5dd472
--- /dev/null
@@ -0,0 +1,37 @@
+/* Test for cross x86_64<->w64 abi va_list calls.  */
+/* { dg-options "-O2 -mabi=ms -std=gnu99 -fno-builtin" } */
+
+#include <stdarg.h>
+
+#define SZ_ARGS        1ll,2ll,3ll,4ll,5ll,6ll,7ll,0ll
+
+static int __attribute__ ((sysv_abi))
+fct1 (va_list argp, ...)
+{
+  long long p1,p2;
+  int ret = 1;
+  __builtin_sysv_va_list argp_2;
+
+  __builtin_sysv_va_start (argp_2, argp);
+  do {
+    p1 = va_arg (argp_2, long long);
+    p2 = va_arg (argp, long long);
+    if (p1 != p2)
+      ret = 0;
+  } while (ret && p1 != 0);
+  __builtin_sysv_va_end (argp_2);
+
+  return ret;
+}
+
+int
+fct2 (int dummy, ...)
+{
+  va_list argp;
+  int ret = dummy;
+
+  va_start (argp, dummy);
+  ret += fct1 (argp, SZ_ARGS);
+  va_end (argp);
+  return ret;
+}