Hi Jan,

Jan Hubicka wrote on 31.07.2007 23:40:40:

> > Hi Kai,
> > 
> > so, could you resolve the remaining issues? Or have you kind of 
> > paused the project?
> > 
> > Cheers,
> > Nicolas
> > 
> > 
> > On Jul 12, 2007, at 2:14 , Kai Tietz wrote:
> > 
> > >Hi,
> > >
> > >I am nearly through :) The remaining macros left to be ported are
> > >REGPARM_MAX and SSE_REGPARM_MAX. The sysv_abi uses 6 regs and 8 sses,
> > >ms_abi uses 4 regs and 4 sse registers. The problem is for example 
> > >the use
> > >in i386.md of SSE_REGPARM_MAX without any hint, how to choose the 
> > >required
> > >abi. Do you have an idea how this could be done ?
> 
> This shoul not be dificult - ix86_regparm is used in
> ix86_function_regparm, init_cumulative_args, setup_incoming_varargs_64
> functions.  In all those cases you know the function declaration and
> thus you can take a look if it is call to different ABI and overwrite
> the value.

Ok, here is my update.

Cheers,
 i.A. Kai Tietz



|  (\_/)  This is Bunny. Copy and paste Bunny
| (='.'=) into your signature to help him gain
| (")_(") world domination.

------------------------------------------------------------------------------------------
  OneVision Software Entwicklungs GmbH & Co. KG
  Dr.-Leo-Ritter-Straße 9 - 93049 Regensburg
  Tel: +49.(0)941.78004.0 - Fax: +49.(0)941.78004.489 - www.OneVision.com
  Commerzbank Regensburg - BLZ 750 400 62 - Konto 6011050
  Handelsregister: HRA 6744, Amtsgericht Regensburg
  Komplementärin: OneVision Software Entwicklungs Verwaltungs GmbH
  Dr.-Leo-Ritter-Straße 9 – 93049 Regensburg
  Handelsregister: HRB 8932, Amtsgericht Regensburg - Geschäftsführer: 
Ulrike Döhler, Manuela Kluger

Index: gcc/gcc/calls.c
===================================================================
--- gcc.orig/gcc/calls.c
+++ gcc/gcc/calls.c
@@ -1187,6 +1187,7 @@ initialize_argument_information (int num
 static int
 compute_argument_block_size (int reg_parm_stack_space,
                             struct args_size *args_size,
+                            tree fndecl, // $$$$
                             int preferred_stack_boundary ATTRIBUTE_UNUSED)
 {
   int unadjusted_args_size = args_size->constant;
@@ -1224,7 +1225,7 @@ compute_argument_block_size (int reg_par
 
          /* The area corresponding to register parameters is not to count in
             the size of the block we need.  So make the adjustment.  */
-         if (!OUTGOING_REG_PARM_STACK_SPACE)
+         if (!OUTGOING_REG_PARM_STACK_SPACE (fndecl))
            args_size->var
              = size_binop (MINUS_EXPR, args_size->var,
                            ssize_int (reg_parm_stack_space));
@@ -1245,7 +1246,7 @@ compute_argument_block_size (int reg_par
       args_size->constant = MAX (args_size->constant,
                                 reg_parm_stack_space);
 
-      if (!OUTGOING_REG_PARM_STACK_SPACE)
+      if (!OUTGOING_REG_PARM_STACK_SPACE (fndecl))
        args_size->constant -= reg_parm_stack_space;
     }
   return unadjusted_args_size;
@@ -2036,7 +2037,7 @@ expand_call (tree exp, rtx target, int i
   reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
 #endif
 
-  if (!OUTGOING_REG_PARM_STACK_SPACE && reg_parm_stack_space > 0 && PUSH_ARGS)
+  if (!OUTGOING_REG_PARM_STACK_SPACE (fndecl) && reg_parm_stack_space > 0 && 
PUSH_ARGS)
     must_preallocate = 1;
 
   /* Set up a place to return a structure.  */
@@ -2442,7 +2443,7 @@ expand_call (tree exp, rtx target, int i
                  /* Since we will be writing into the entire argument area,
                     the map must be allocated for its entire size, not just
                     the part that is the responsibility of the caller.  */
-                 if (!OUTGOING_REG_PARM_STACK_SPACE)
+                 if (!OUTGOING_REG_PARM_STACK_SPACE (fndecl))
                    needed += reg_parm_stack_space;
 
 #ifdef ARGS_GROW_DOWNWARD
@@ -2541,7 +2542,7 @@ expand_call (tree exp, rtx target, int i
            {
              rtx push_size
                = GEN_INT (adjusted_args_size.constant
-                          + (OUTGOING_REG_PARM_STACK_SPACE ? 0
+                          + (OUTGOING_REG_PARM_STACK_SPACE (fndecl) ? 0
                              : reg_parm_stack_space));
              if (old_stack_level == 0)
                {
@@ -2712,7 +2713,7 @@ expand_call (tree exp, rtx target, int i
       /* If register arguments require space on the stack and stack space
         was not preallocated, allocate stack space here for arguments
         passed in registers.  */
-      if (OUTGOING_REG_PARM_STACK_SPACE && !ACCUMULATE_OUTGOING_ARGS
+      if (OUTGOING_REG_PARM_STACK_SPACE (fndecl) && !ACCUMULATE_OUTGOING_ARGS
          && must_preallocate == 0 && reg_parm_stack_space > 0)
        anti_adjust_stack (GEN_INT (reg_parm_stack_space));
 
@@ -3537,7 +3538,7 @@ emit_library_call_value_1 (int retval, r
   args_size.constant = MAX (args_size.constant,
                            reg_parm_stack_space);
 
-  if (!OUTGOING_REG_PARM_STACK_SPACE)
+  if (!OUTGOING_REG_PARM_STACK_SPACE (fndecl))
     args_size.constant -= reg_parm_stack_space;
 
   if (args_size.constant > current_function_outgoing_args_size)
@@ -3562,7 +3563,7 @@ emit_library_call_value_1 (int retval, r
       /* Since we will be writing into the entire argument area, the
         map must be allocated for its entire size, not just the part that
         is the responsibility of the caller.  */
-      if (!OUTGOING_REG_PARM_STACK_SPACE)
+      if (!OUTGOING_REG_PARM_STACK_SPACE (fndecl))
        needed += reg_parm_stack_space;
 
 #ifdef ARGS_GROW_DOWNWARD
Index: gcc/gcc/config/alpha/unicosmk.h
===================================================================
--- gcc.orig/gcc/config/alpha/unicosmk.h
+++ gcc/gcc/config/alpha/unicosmk.h
@@ -116,7 +116,7 @@ Boston, MA 02110-1301, USA.  */
    in registers) are allocated.  */
 
 #define REG_PARM_STACK_SPACE(DECL) 48
-#define OUTGOING_REG_PARM_STACK_SPACE 1
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL) 1
 
 /* If an argument can't be passed in registers even though not all argument
    registers have been used yet, it is passed on the stack in the space 
Index: gcc/gcc/config/bfin/bfin.h
===================================================================
--- gcc.orig/gcc/config/bfin/bfin.h
+++ gcc/gcc/config/bfin/bfin.h
@@ -211,7 +211,7 @@ extern const char *bfin_library_id_strin
 
 /* Define this if the above stack space is to be considered part of the
  * space allocated by the caller.  */
-#define OUTGOING_REG_PARM_STACK_SPACE 1
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL) 1
          
 /* Define this if the maximum size of all the outgoing args is to be
    accumulated and pushed during the prologue.  The amount can be
Index: gcc/gcc/config/i386/cygming.h
===================================================================
--- gcc.orig/gcc/config/i386/cygming.h
+++ gcc/gcc/config/i386/cygming.h
@@ -35,7 +35,10 @@ Boston, MA 02110-1301, USA.  */
 #endif
 
 #undef TARGET_64BIT_MS_ABI
-#define TARGET_64BIT_MS_ABI TARGET_64BIT
+#define TARGET_64BIT_MS_ABI (!cfun ? DEFAULT_USED_ABI == 1 : TARGET_64BIT && 
cfun->machine->used_abi == 1)
+
+#undef DEFAULT_USED_ABI
+#define DEFAULT_USED_ABI (TARGET_64BIT ? 1 : 0)
 
 #undef DBX_REGISTER_NUMBER
 #define DBX_REGISTER_NUMBER(n)                         \
@@ -124,12 +127,6 @@ Boston, MA 02110-1301, USA.  */
 #undef LONG_TYPE_SIZE
 #define LONG_TYPE_SIZE 32
 
-#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 (TARGET_64BIT_MS_ABI ? 1 : 0)
-
 #undef REGPARM_MAX
 #define REGPARM_MAX (TARGET_64BIT_MS_ABI ? 4 : 3)
 
Index: gcc/gcc/config/i386/i386-protos.h
===================================================================
--- gcc.orig/gcc/config/i386/i386-protos.h
+++ gcc/gcc/config/i386/i386-protos.h
@@ -134,7 +134,7 @@ extern rtx ix86_libcall_value (enum mach
 extern bool ix86_function_value_regno_p (int);
 extern bool ix86_function_arg_regno_p (int);
 extern int ix86_function_arg_boundary (enum machine_mode, tree);
-extern int ix86_return_in_memory (tree);
+extern int ix86_return_in_memory (tree, tree);
 extern int ix86_sol10_return_in_memory (tree);
 extern void ix86_va_start (tree, rtx);
 extern rtx ix86_va_arg (tree, tree);
Index: gcc/gcc/config/i386/i386.c
===================================================================
--- gcc.orig/gcc/config/i386/i386.c
+++ gcc/gcc/config/i386/i386.c
@@ -1408,7 +1408,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 (6 * UNITS_PER_WORD + 8 * 16)
 
 /* Define the structure for the machine field in struct function.  */
 
@@ -1981,11 +1981,11 @@ override_options (void)
     }
   else
     {
-      /* For TARGET_64BIT_MS_ABI, force pic on, in order to enable the
+      /* For DEFAULT_USED_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 (DEFAULT_USED_ABI == 1)
        ix86_cmodel = CM_SMALL_PIC, flag_pic = 1;
       else if (TARGET_64BIT)
        ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
@@ -2806,7 +2806,7 @@ ix86_handle_cconv_attribute (tree *node,
   if (TARGET_64BIT)
     {
       /* Do not warn when emulating the MS ABI.  */
-      if (!TARGET_64BIT_MS_ABI)
+      if (TREE_CODE (*node) != FUNCTION_TYPE || !ix86_get_abi_format (*node))
        warning (OPT_Wattributes, "%qs attribute ignored",
                 IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
@@ -2906,7 +2906,11 @@ ix86_function_regparm (tree type, tree d
   int regparm = ix86_regparm;
 
   if (TARGET_64BIT)
-    return regparm;
+    {
+      if (ix86_get_abi_format () == DEFAULT_USED_ABI)
+        return regparm;
+      return DEFAULT_USED_ABI != 0 ? 6 : 4;
+    }
 
   attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
   if (attr)
@@ -3127,11 +3131,15 @@ 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 == 0)
+  if (DEFAULT_USED_ABI != 1 && regno == 0)
     return true;
 
-  if (TARGET_64BIT_MS_ABI)
+  if (DEFAULT_USED_ABI == 1)
     parm_regs = x86_64_ms_abi_int_parameter_registers;
   else
     parm_regs = x86_64_int_parameter_registers;
@@ -3156,6 +3164,38 @@ ix86_must_pass_in_stack (enum machine_mo
          && 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 (tree fndecl)
+{
+  int used_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)
+    used_abi = DEFAULT_USED_ABI;
+  else
+    used_abi = ix86_get_abi_format (TREE_TYPE (fndecl));
+  if (used_abi == 1)
+    return 32;
+  return 0;
+}
+
+/* Returns value 0 for sysv_abi and value 1 for ms_abi.  */
+int
+ix86_get_abi_format (tree fntype)
+{
+  if (TARGET_64BIT && fntype != NULL)
+    {
+      if (DEFAULT_USED_ABI == 0)
+        return lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)) ? 1 : 0;
+      else 
+        return lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)) ? 0 : 1;
+    }
+  return DEFAULT_USED_ABI;
+}
+
 /* 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.  */
@@ -3168,10 +3208,23 @@ init_cumulative_args (CUMULATIVE_ARGS *c
 {
   memset (cum, 0, sizeof (*cum));
 
+  cum->used_abi = ix86_get_abi_format (fntype);
   /* Set up the number of registers to use for passing arguments.  */
-  cum->nregs = ix86_regparm;
+  if (TARGET_64BIT)
+    {
+      cum->nregs = ix86_regparm;
+      if (cum->used_abi != DEFAULT_USED_ABI)
+        cum->nregs = DEFAULT_USED_ABI != 0 ? 6 : 4;
+    }
   if (TARGET_SSE)
-    cum->sse_nregs = SSE_REGPARM_MAX;
+    {
+      cum->sse_nregs = SSE_REGPARM_MAX;
+      if (TARGET_64BIT)
+        {
+          if (cum->used_abi != DEFAULT_USED_ABI)
+            cum->sse_nregs = DEFAULT_USED_ABI != 0 ? 8 : 4;
+        }
+    }
   if (TARGET_MMX)
     cum->mmx_nregs = MMX_REGPARM_MAX;
   cum->warn_sse = true;
@@ -3947,7 +4000,7 @@ function_arg_advance (CUMULATIVE_ARGS *c
   if (type)
     mode = type_natural_mode (type);
 
-  if (TARGET_64BIT_MS_ABI)
+  if (cum->used_abi == 1)
     function_arg_advance_ms_64 (cum, bytes, words);
   else if (TARGET_64BIT)
     function_arg_advance_64 (cum, mode, type, words);
@@ -4070,7 +4123,9 @@ function_arg_64 (CUMULATIVE_ARGS *cum, e
   if (mode == VOIDmode)
     return GEN_INT (cum->maybe_vaarg
                    ? (cum->sse_nregs < 0
-                      ? SSE_REGPARM_MAX
+                      ? ((!TARGET_64BIT
+                          || cum->used_abi == DEFAULT_USED_ABI) ? 
SSE_REGPARM_MAX
+                                                                : 
(DEFAULT_USED_ABI != 0 ? 8 : 4))
                       : cum->sse_regno)
                    : -1);
 
@@ -4136,7 +4191,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum
   if (type && TREE_CODE (type) == VECTOR_TYPE)
     mode = type_natural_mode (type);
 
-  if (TARGET_64BIT_MS_ABI)
+  if (cum->used_abi == 1)
     return function_arg_ms_64 (cum, mode, omode, named);
   else if (TARGET_64BIT)
     return function_arg_64 (cum, mode, omode, type);
@@ -4151,11 +4206,11 @@ function_arg (CUMULATIVE_ARGS *cum, enum
    appropriate for passing a pointer to that type.  */
 
 static bool
-ix86_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ix86_pass_by_reference (CUMULATIVE_ARGS *cum,
                        enum machine_mode mode ATTRIBUTE_UNUSED,
                        tree type, bool named ATTRIBUTE_UNUSED)
 {
-  if (TARGET_64BIT_MS_ABI)
+  if (cum->used_abi == 1)
     {
       if (type)
        {
@@ -4281,7 +4336,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 (DEFAULT_USED_ABI == 1)
        return false;
       return TARGET_FLOAT_RETURNS_IN_80387;
 
@@ -4372,7 +4430,7 @@ function_value_64 (enum machine_mode ori
     }
 
   ret = construct_container (mode, orig_mode, valtype, 1,
-                            REGPARM_MAX, SSE_REGPARM_MAX,
+                            6, 8,
                             x86_64_int_return_registers, 0);
 
   /* For zero sized structures, construct_container returns NULL, but we
@@ -4410,7 +4468,7 @@ ix86_function_value_1 (tree valtype, tre
     fn = fntype_or_decl;
   fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
 
-  if (TARGET_64BIT_MS_ABI)
+  if (ix86_get_abi_format (fntype) == 1)
     return function_value_ms_64 (orig_mode, mode);
   else if (TARGET_64BIT)
     return function_value_64 (orig_mode, mode, valtype);
@@ -4498,11 +4556,11 @@ return_in_memory_ms_64 (tree type, enum 
 }
 
 int
-ix86_return_in_memory (tree type)
+ix86_return_in_memory (tree type, tree fntype)
 {
   enum machine_mode mode = type_natural_mode (type);
 
-  if (TARGET_64BIT_MS_ABI)
+  if (ix86_get_abi_format (fntype) == 1)
     return return_in_memory_ms_64 (type, mode);
   else if (TARGET_64BIT)
     return return_in_memory_64 (type, mode);
@@ -4602,7 +4660,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 || cfun->machine->used_abi == 1)
     return build_pointer_type (char_type_node);
 
   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
@@ -4650,6 +4708,10 @@ setup_incoming_varargs_64 (CUMULATIVE_AR
   rtx nsse_reg;
   int set;
   int i;
+  int regparm = ix86_regparm;
+  
+  if(cum->used_abi != DEFAULT_USED_ABI)
+    regparm = DEFAULT_USED_ABI != 0 ? 6 : 4;
 
   if (! cfun->va_list_gpr_size && ! cfun->va_list_fpr_size)
     return;
@@ -4662,7 +4724,7 @@ setup_incoming_varargs_64 (CUMULATIVE_AR
   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++)
     {
@@ -4769,7 +4831,7 @@ ix86_setup_incoming_varargs (CUMULATIVE_
   if (stdarg_p)
     function_arg_advance (&next_cum, mode, type, 1);
 
-  if (TARGET_64BIT_MS_ABI)
+  if (cum->used_abi == 1)
     setup_incoming_varargs_ms_64 (&next_cum);
   else
     setup_incoming_varargs_64 (&next_cum);
@@ -4786,7 +4848,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->used_abi == 1)
     {
       std_expand_builtin_va_start (valist, nextarg);
       return;
@@ -4865,7 +4927,7 @@ ix86_gimplify_va_arg (tree valist, tree 
   enum machine_mode nat_mode;
 
   /* Only 64bit target needs something special.  */
-  if (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
+  if (!TARGET_64BIT || cfun->machine->used_abi == 1)
     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
 
   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
@@ -4887,7 +4949,7 @@ ix86_gimplify_va_arg (tree valist, tree 
 
   nat_mode = type_natural_mode (type);
   container = construct_container (nat_mode, TYPE_MODE (type), type, 0,
-                                  REGPARM_MAX, SSE_REGPARM_MAX, intreg, 0);
+                                  6, 8, intreg, 0);
 
   /* Pull the value out of the saved registers.  */
 
@@ -4965,7 +5027,7 @@ ix86_gimplify_va_arg (tree valist, tree 
       if (needed_sseregs)
        {
          t = build_int_cst (TREE_TYPE (fpr),
-                            (SSE_REGPARM_MAX - needed_sseregs + 1) * 16
+                            (8 - needed_sseregs + 1) * 16
                             + REGPARM_MAX * 8);
          t = build2 (GE_EXPR, boolean_type_node, fpr, t);
          t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
@@ -6065,9 +6127,9 @@ ix86_expand_prologue (void)
       bool eax_live;
       rtx t;
 
-      gcc_assert (!TARGET_64BIT || TARGET_64BIT_MS_ABI);
+      gcc_assert (!TARGET_64BIT || cfun->machine->used_abi == 1);
 
-      if (TARGET_64BIT_MS_ABI)
+      if (cfun->machine->used_abi == 1)
        eax_live = false;
       else
        eax_live = ix86_eax_live_at_start_p ();
@@ -7250,7 +7312,7 @@ legitimize_pic_address (rtx orig, rtx re
       /* Given that we've already handled dllimport variables separately
         in legitimize_address, and all other variables should satisfy
         legitimate_pic_address_disp_p, we should never arrive here.  */
-      gcc_assert (!TARGET_64BIT_MS_ABI);
+      gcc_assert (cfun->machine->used_abi != 1);
 
       if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
        {
@@ -7874,7 +7936,7 @@ output_pic_addr_const (FILE *file, rtx x
 #endif
          assemble_name (file, name);
        }
-      if (!TARGET_MACHO && !TARGET_64BIT_MS_ABI
+      if (!TARGET_MACHO && cfun->machine->used_abi != 1
          && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
        fputs ("@PLT", file);
       break;
@@ -15591,7 +15653,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->used_abi = DEFAULT_USED_ABI;
   return f;
 }
 
@@ -21091,7 +21153,7 @@ x86_this_parameter (tree function)
     {
       const int *parm_regs;
 
-      if (TARGET_64BIT_MS_ABI)
+      if (ix86_get_abi_format (type) == 1)
         parm_regs = x86_64_ms_abi_int_parameter_registers;
       else
         parm_regs = x86_64_int_parameter_registers;
@@ -21240,7 +21302,7 @@ x86_output_mi_thunk (FILE *file ATTRIBUT
        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 (cfun->machine->used_abi == 1)
        gcc_unreachable ();
       else
        {
@@ -21323,7 +21385,7 @@ x86_function_profiler (FILE *file, int l
       fprintf (file, "\tleaq\t%sP%d@(%%rip),%%r11\n", LPREFIX, labelno);
 #endif
 
-      if (!TARGET_64BIT_MS_ABI && flag_pic)
+      if (!DEFAULT_USED_ABI && flag_pic)
        fprintf (file, "[EMAIL PROTECTED](%%rip)\n", MCOUNT_NAME);
       else
        fprintf (file, "\tcall\t%s\n", MCOUNT_NAME);
Index: gcc/gcc/config/i386/i386.h
===================================================================
--- gcc.orig/gcc/config/i386/i386.h
+++ gcc/gcc/config/i386/i386.h
@@ -415,7 +415,10 @@ 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 (!cfun ? DEFAULT_USED_ABI == 1 : TARGET_64BIT && 
cfun->machine->used_abi == 1)
+
+/* The default abi form used by target.  */
+#define DEFAULT_USED_ABI 0
 
 /* Subtargets may reset this to 1 in order to enable 96-bit long double
    with the rounding mode forced to 53 bits.  */
@@ -982,6 +985,25 @@ extern const char *host_detect_local_cpu
 
 #define ORDER_REGS_FOR_LOCAL_ALLOC x86_order_regs_for_local_alloc ()
 
+extern int ix86_get_abi_format (tree fntype);
+
+#define OVERRIDE_ABI_FORMAT (FNDECL) \
+do {                                                                   \
+    if (FNDECL == NULL)                                                        
\
+      cfun->machine->used_abi = DEFAULT_USED_ABI;                      \
+    else                                                               \
+      cfun->machine->used_abi = ix86_get_abi_format (TREE_TYPE (FNDECL));      
\
+    if (cfun->machine->used_abi == 1)                                          
\
+      {                                                                        
\
+        call_used_regs[4 /*RSI*/] = 0;                                  \
+        call_used_regs[5 /*RDI*/] = 0;                                  \
+      }                                                                        
\
+    else if (TARGET_64BIT)                                             \
+      {                                                                        
\
+        call_used_regs[4 /*RSI*/] = 1;                                  \
+        call_used_regs[5 /*RDI*/] = 1;                                  \
+      }                                                                        
\
+   } while (0)
 
 /* Macro to conditionally modify fixed_regs/call_used_regs.  */
 #define CONDITIONAL_REGISTER_USAGE                                     \
@@ -1033,11 +1055,6 @@ do {                                                     
                \
        for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)         \
          reg_names[i] = "";                                            \
       }                                                                        
\
-    if (TARGET_64BIT_MS_ABI)                                           \
-      {                                                                        
\
-        call_used_regs[4 /*RSI*/] = 0;                                  \
-        call_used_regs[5 /*RDI*/] = 0;                                  \
-      }                                                                        
\
   } while (0)
 
 /* Return number of consecutive hard regs needed starting at reg REGNO
@@ -1227,8 +1244,8 @@ do {                                                      
                \
    should always be returned in memory.  You should instead use
    `DEFAULT_PCC_STRUCT_RETURN' to indicate this.  */
 
-#define RETURN_IN_MEMORY(TYPE) \
-  ix86_return_in_memory (TYPE)
+#define RETURN_IN_MEMORY(TYPE, FNTYPE) \
+  ix86_return_in_memory (TYPE, FNTYPE)
 
 /* This is overridden by <cygwin.h>.  */
 #define MS_AGGREGATE_RETURN 0
@@ -1576,7 +1593,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(FNDECL) ((FNDECL) && ix86_get_abi_format 
(TREE_TYPE (FNDECL)) == 1 ? 1 : 0)
+
+extern unsigned int ix86_reg_parm_stack_space (tree);
 
 /* Value is the number of bytes of arguments automatically
    popped when returning from a subroutine call.
@@ -1638,6 +1659,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 used_abi;                        /* Set to zero for sysv_abi. Otherwise
+                                  1 for ms_abi.  */
 } CUMULATIVE_ARGS;
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
@@ -2420,6 +2443,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. One means ms_abi. Otherwise 0 means sysv_abi.  */
+  int used_abi;
 };
 
 #define ix86_stack_locals (cfun->machine->stack_locals)
Index: gcc/gcc/config/iq2000/iq2000.h
===================================================================
--- gcc.orig/gcc/config/iq2000/iq2000.h
+++ gcc/gcc/config/iq2000/iq2000.h
@@ -375,7 +375,7 @@ enum reg_class
 
 #define REG_PARM_STACK_SPACE(FNDECL) 0
 
-#define OUTGOING_REG_PARM_STACK_SPACE 1
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL) 1
 
 #define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
 
Index: gcc/gcc/config/mips/mips.h
===================================================================
--- gcc.orig/gcc/config/mips/mips.h
+++ gcc/gcc/config/mips/mips.h
@@ -1897,7 +1897,7 @@ extern const enum reg_class mips_regno_t
    If `ACCUMULATE_OUTGOING_ARGS' is also defined, the only effect
    of this macro is to determine whether the space is included in
    `current_function_outgoing_args_size'.  */
-#define OUTGOING_REG_PARM_STACK_SPACE 1
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL) 1
 
 #define STACK_BOUNDARY (TARGET_NEWABI ? 128 : 64)
 
Index: gcc/gcc/config/mn10300/mn10300.h
===================================================================
--- gcc.orig/gcc/config/mn10300/mn10300.h
+++ gcc/gcc/config/mn10300/mn10300.h
@@ -487,7 +487,7 @@ enum reg_class {
 /* We use d0/d1 for passing parameters, so allocate 8 bytes of space
    for a register flushback area.  */
 #define REG_PARM_STACK_SPACE(DECL) 8
-#define OUTGOING_REG_PARM_STACK_SPACE 1
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL) 1
 #define ACCUMULATE_OUTGOING_ARGS 1
 
 /* So we can allocate space for return pointers once for the function
Index: gcc/gcc/config/mt/mt.h
===================================================================
--- gcc.orig/gcc/config/mt/mt.h
+++ gcc/gcc/config/mt/mt.h
@@ -533,7 +533,7 @@ extern struct mt_frame_info current_fram
 
 /* Define this if it is the responsibility of the caller to
    allocate the area reserved for arguments passed in registers.  */
-#define OUTGOING_REG_PARM_STACK_SPACE 1
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL) 1
 
 /* The number of register assigned to holding function arguments.  */
 #define MT_NUM_ARG_REGS        4
Index: gcc/gcc/config/pa/pa.h
===================================================================
--- gcc.orig/gcc/config/pa/pa.h
+++ gcc/gcc/config/pa/pa.h
@@ -560,7 +560,7 @@ extern struct rtx_def *hppa_pic_save_rtx
 
 /* Define this if the above stack space is to be considered part of the
    space allocated by the caller.  */
-#define OUTGOING_REG_PARM_STACK_SPACE 1
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL) 1
 
 /* Keep the stack pointer constant throughout the function.
    This is both an optimization and a necessity: longjmp
Index: gcc/gcc/config/rs6000/rs6000.h
===================================================================
--- gcc.orig/gcc/config/rs6000/rs6000.h
+++ gcc/gcc/config/rs6000/rs6000.h
@@ -1257,7 +1257,7 @@ extern enum rs6000_abi rs6000_current_ab
 
 /* Define this if the above stack space is to be considered part of the
    space allocated by the caller.  */
-#define OUTGOING_REG_PARM_STACK_SPACE 1
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL) 1
 
 /* This is the difference between the logical top of stack and the actual sp.
 
Index: gcc/gcc/config/score/score.h
===================================================================
--- gcc.orig/gcc/config/score/score.h
+++ gcc/gcc/config/score/score.h
@@ -546,7 +546,7 @@ enum reg_class
    If `ACCUMULATE_OUTGOING_ARGS' is also defined, the only effect
    of this macro is to determine whether the space is included in
    `current_function_outgoing_args_size'.  */
-#define OUTGOING_REG_PARM_STACK_SPACE   1
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL)   1
 
 #define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
 
Index: gcc/gcc/config/spu/spu.h
===================================================================
--- gcc.orig/gcc/config/spu/spu.h
+++ gcc/gcc/config/spu/spu.h
@@ -354,7 +354,7 @@ targetm.resolve_overloaded_builtin = spu
 
 #define REG_PARM_STACK_SPACE(FNDECL) 0
 
-#define OUTGOING_REG_PARM_STACK_SPACE 1
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL) 1
 
 #define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) (0)
 
Index: gcc/gcc/config/v850/v850.h
===================================================================
--- gcc.orig/gcc/config/v850/v850.h
+++ gcc/gcc/config/v850/v850.h
@@ -626,7 +626,7 @@ struct cum_arg { int nbytes; int anonymo
 
 /* Define this if the above stack space is to be considered part of the
    space allocated by the caller.  */
-#define OUTGOING_REG_PARM_STACK_SPACE 1
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL) 1
 
 /* 1 if N is a possible register number for function argument passing.  */
 
Index: gcc/gcc/defaults.h
===================================================================
--- gcc.orig/gcc/defaults.h
+++ gcc/gcc/defaults.h
@@ -905,7 +905,7 @@ along with GCC; see the file COPYING3.  
 #endif
 
 #ifndef OUTGOING_REG_PARM_STACK_SPACE
-#define OUTGOING_REG_PARM_STACK_SPACE 0
+#define OUTGOING_REG_PARM_STACK_SPACE(FNDECL) 0
 #endif
 
 #endif  /* ! GCC_DEFAULTS_H */
Index: gcc/gcc/expr.c
===================================================================
--- gcc.orig/gcc/expr.c
+++ gcc/gcc/expr.c
@@ -1233,6 +1233,8 @@ emit_block_move (rtx x, rtx y, rtx size,
 static bool
 block_move_libcall_safe_for_call_parm (void)
 {
+  tree fn;
+
   /* If arguments are pushed on the stack, then they're safe.  */
   if (PUSH_ARGS)
     return true;
@@ -1240,13 +1242,9 @@ block_move_libcall_safe_for_call_parm (v
   /* If registers go on the stack anyway, any argument is sure to clobber
      an outgoing argument.  */
 #if defined (REG_PARM_STACK_SPACE)
-  if (OUTGOING_REG_PARM_STACK_SPACE)
-    {
-      tree fn;
-      fn = emit_block_move_libcall_fn (false);
-      if (REG_PARM_STACK_SPACE (fn) != 0)
-       return false;
-    }
+  fn = emit_block_move_libcall_fn (false);
+  if (OUTGOING_REG_PARM_STACK_SPACE (fn) && REG_PARM_STACK_SPACE (fn) != 0)
+    return false;
 #endif
 
   /* If any argument goes in memory, then it might clobber an outgoing
Index: gcc/gcc/function.c
===================================================================
--- gcc.orig/gcc/function.c
+++ gcc/gcc/function.c
@@ -1216,7 +1216,7 @@ static int cfa_offset;
 #define STACK_DYNAMIC_OFFSET(FNDECL)   \
 ((ACCUMULATE_OUTGOING_ARGS                                                   \
   ? (current_function_outgoing_args_size                                     \
-     + (OUTGOING_REG_PARM_STACK_SPACE ? 0 : REG_PARM_STACK_SPACE (FNDECL)))   \
+     + (OUTGOING_REG_PARM_STACK_SPACE (FNDECL) ? 0 : REG_PARM_STACK_SPACE 
(FNDECL)))   \
   : 0) + (STACK_POINTER_OFFSET))
 #else
 #define STACK_DYNAMIC_OFFSET(FNDECL)   \
@@ -3813,12 +3813,15 @@ allocate_struct_function (tree fndecl)
   if (init_machine_status)
     cfun->machine = (*init_machine_status) ();
 
+#ifdef OVERRIDE_ABI_FORM
+  OVERRIDE_ABI_FORMAT (fndecl);
+#endif
+
   if (fndecl == NULL)
     return;
 
   DECL_STRUCT_FUNCTION (fndecl) = cfun;
   cfun->decl = fndecl;
-
   result = DECL_RESULT (fndecl);
   if (aggregate_value_p (result, fndecl))
     {
Index: gcc/gcc/targhooks.c
===================================================================
--- gcc.orig/gcc/targhooks.c
+++ gcc/gcc/targhooks.c
@@ -90,7 +90,7 @@ default_return_in_memory (tree type,
 #ifndef RETURN_IN_MEMORY
   return (TYPE_MODE (type) == BLKmode);
 #else
-  return RETURN_IN_MEMORY (type);
+  return RETURN_IN_MEMORY (type, fntype);
 #endif
 }
 
=

Reply via email to