OSDN Git Service

gcc/
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Mar 2007 21:45:03 +0000 (21:45 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Mar 2007 21:45:03 +0000 (21:45 +0000)
* config/i386/cygming.h (DWARF2_DEBUGGING_INFO): Enable by
default for 64-bit.
(PREFERRED_DEBUGGING_TYPE): Prefer dwarf2 for 64-bit.
(TARGET_64BIT_MS_ABI): New.
(DBX_REGISTER_NUMBER): Handle 64-bit.
(SIZE_TYPE, PTRDIFF_TYPE): Use long long for 64-bit.
(LONG_TYPE_SIZE): Force to 32.
(REG_PARM_STACK_SPACE): New.
(OUTGOING_REG_PARM_STACK_SPACE): New.
(REGPARM_MAX, SSE_REGPARM_MAX): New.
(HANDLE_PRAGMA_PUSH_POP_MACRO): New.
(STACK_BOUNDARY): Use 128 for 64-bit.
* config/i386/cygwin.asm: Use push/ret to preserve call stack.
Add 64-bit implementation.
* config/i386/gthr-win32.c (__gthr_win32_key_create): Mark dtor
argument unused.
* config/i386/i386.c (x86_64_ms_abi_int_parameter_registers): New.
(override_options): Set ix86_cmodel for TARGET_64BIT_MS_ABI.
Warn for -mregparm, -mrtd in 64-bit mode; force ix86_regparm
for 64-bit; use TARGET_SUBTARGET64_DEFAULT.
(ix86_handle_cconv_attribute): Don't warn when ignoring if
TARGET_64BIT_MS_ABI.
(ix86_function_arg_regno_p): Handle TARGET_64BIT_MS_ABI.
(ix86_pass_by_reference): Likewise.
(ix86_function_value_regno_p): Likewise.
(ix86_build_builtin_va_list): Likewise.
(ix86_va_start, ix86_gimplify_va_arg): Likewise.
(function_arg_advance_ms_64): New.
(function_arg_advance): Call it.
(function_arg_ms_64): New.
(function_arg): Call it.
(function_value_ms_64): New.
(ix86_function_value_1): Call it.
(return_in_memory_ms_64): New.
(ix86_return_in_memory): Call it.
(setup_incoming_varargs_ms_64): New.
(ix86_setup_incoming_varargs): Call it.
(ix86_expand_prologue): Handle 64-bit stack probing.
(legitimize_pic_address): Handle TARGET_64BIT_MS_ABI.
(output_pic_addr_const): Likewise.
(x86_this_parameter): Likewise.
(x86_output_mi_thunk): Likewise.
(x86_function_profiler): Likewise.
(TARGET_STRICT_ARGUMENT_NAMING): New.
* config/i386/i386.h (TARGET_SUBTARGET64_DEFAULT): New.
(TARGET_64BIT_MS_ABI): New.
(CONDITIONAL_REGISTER_USAGE): Handle TARGET_64BIT_MS_ABI.
* config/i386/i386.md (allocate_stack_worker): Remove.
(allocate_stack_worker_32): Rename from allocate_stack_worker_1;
describe the clobber of eax without a match_scratch.
(allocate_stack_worker_postreload): Remove.
(allocate_stack_worker_64): Rename from allocate_stack_worker_rex64;
describe the clobbers of rax, r10, r11 properly; use __chkstk symbol.
(allocate_stack_worker_rex64_postreload): Remove.
(allocate_stack): Handle 64-bit.
* config/i386/i386elf (TARGET_SUBTARGET_DEFAULT): Remove.
* config/i386/mingw32.h (TARGET_VERSION): Set correctly for 64-bit.
(EXTRA_OS_CPP_BUILTINS): Handle 64-bit.
(STANDARD_INCLUDE_DIR): Handle TARGET_64BIT_DEFAULT.
(STANDARD_STARTFILE_PREFIX_1): Likewise.
* config/i386/unix.h (TARGET_SUBTARGET64_DEFAULT): New.
* config.build (x86_64-*-mingw*): New host.
* config.host (x86_64-*-mingw*): New host.
* config.gcc (x86_64-*-mingw*): New target.
* gthr-win32.h (__gthread_key_create): Mark dtor unused.
libgcc/
* config.host (x86_64-*-mingw*): New target.

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

16 files changed:
gcc/ChangeLog
gcc/config.build
gcc/config.gcc
gcc/config.host
gcc/config/i386/cygming.h
gcc/config/i386/cygwin.asm
gcc/config/i386/gthr-win32.c
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md
gcc/config/i386/i386elf.h
gcc/config/i386/mingw32.h
gcc/config/i386/unix.h
gcc/gthr-win32.h
libgcc/ChangeLog
libgcc/config.host

index 1f01dac..b048bc7 100644 (file)
@@ -1,4 +1,81 @@
 2007-03-30  Richard Henderson  <rth@redhat.com>
+
+       * tree-ssa-loop-ivopts.c: Include target.h.
+       (produce_memory_decl_rtl): Pass the rtx through encode_section_info.
+       (get_address_cost): Force SYMBOL_FLAG_LOCAL set.
+       (force_expr_to_var_cost): Use produce_memory_decl_rtl.
+       * Makefile.in (tree-ssa-loop-ivopts.o): Depend on TARGET_H.
+
+2007-03-30  Richard Henderson  <rth@redhat.com>
+           Kai Tietz  <kai.tietz@onevision.com>
+
+       * config/i386/cygming.h (DWARF2_DEBUGGING_INFO): Enable by
+       default for 64-bit.
+       (PREFERRED_DEBUGGING_TYPE): Prefer dwarf2 for 64-bit.
+       (TARGET_64BIT_MS_ABI): New.
+       (DBX_REGISTER_NUMBER): Handle 64-bit.
+       (SIZE_TYPE, PTRDIFF_TYPE): Use long long for 64-bit.
+       (LONG_TYPE_SIZE): Force to 32.
+       (REG_PARM_STACK_SPACE): New.
+       (OUTGOING_REG_PARM_STACK_SPACE): New.
+       (REGPARM_MAX, SSE_REGPARM_MAX): New.
+       (HANDLE_PRAGMA_PUSH_POP_MACRO): New.
+       (STACK_BOUNDARY): Use 128 for 64-bit.
+       * config/i386/cygwin.asm: Use push/ret to preserve call stack.
+       Add 64-bit implementation.
+       * config/i386/gthr-win32.c (__gthr_win32_key_create): Mark dtor
+       argument unused.
+       * config/i386/i386.c (x86_64_ms_abi_int_parameter_registers): New.
+       (override_options): Set ix86_cmodel for TARGET_64BIT_MS_ABI.
+       Warn for -mregparm, -mrtd in 64-bit mode; force ix86_regparm
+       for 64-bit; use TARGET_SUBTARGET64_DEFAULT.
+       (ix86_handle_cconv_attribute): Don't warn when ignoring if
+       TARGET_64BIT_MS_ABI.
+       (ix86_function_arg_regno_p): Handle TARGET_64BIT_MS_ABI.
+       (ix86_pass_by_reference): Likewise.
+       (ix86_function_value_regno_p): Likewise.
+       (ix86_build_builtin_va_list): Likewise.
+       (ix86_va_start, ix86_gimplify_va_arg): Likewise.
+       (function_arg_advance_ms_64): New.
+       (function_arg_advance): Call it.
+       (function_arg_ms_64): New.
+       (function_arg): Call it.
+       (function_value_ms_64): New.
+       (ix86_function_value_1): Call it.
+       (return_in_memory_ms_64): New.
+       (ix86_return_in_memory): Call it.
+       (setup_incoming_varargs_ms_64): New.
+       (ix86_setup_incoming_varargs): Call it.
+       (ix86_expand_prologue): Handle 64-bit stack probing.
+       (legitimize_pic_address): Handle TARGET_64BIT_MS_ABI.
+       (output_pic_addr_const): Likewise.
+       (x86_this_parameter): Likewise.
+       (x86_output_mi_thunk): Likewise.
+       (x86_function_profiler): Likewise.
+       (TARGET_STRICT_ARGUMENT_NAMING): New.
+       * config/i386/i386.h (TARGET_SUBTARGET64_DEFAULT): New.
+       (TARGET_64BIT_MS_ABI): New.
+       (CONDITIONAL_REGISTER_USAGE): Handle TARGET_64BIT_MS_ABI.
+       * config/i386/i386.md (allocate_stack_worker): Remove.
+       (allocate_stack_worker_32): Rename from allocate_stack_worker_1;
+       describe the clobber of eax without a match_scratch.
+       (allocate_stack_worker_postreload): Remove.
+       (allocate_stack_worker_64): Rename from allocate_stack_worker_rex64;
+       describe the clobbers of rax, r10, r11 properly; use __chkstk symbol.
+       (allocate_stack_worker_rex64_postreload): Remove.
+       (allocate_stack): Handle 64-bit.
+       * config/i386/i386elf (TARGET_SUBTARGET_DEFAULT): Remove.
+       * config/i386/mingw32.h (TARGET_VERSION): Set correctly for 64-bit.
+       (EXTRA_OS_CPP_BUILTINS): Handle 64-bit.
+       (STANDARD_INCLUDE_DIR): Handle TARGET_64BIT_DEFAULT.
+       (STANDARD_STARTFILE_PREFIX_1): Likewise.
+       * config/i386/unix.h (TARGET_SUBTARGET64_DEFAULT): New.
+       * config.build (x86_64-*-mingw*): New host.
+       * config.host (x86_64-*-mingw*): New host.
+       * config.gcc (x86_64-*-mingw*): New target.
+       * gthr-win32.h (__gthread_key_create): Mark dtor unused.
+
+2007-03-30  Richard Henderson  <rth@redhat.com>
            Kai Tietz  <kai.tietz@onevision.com>
 
        * c-pragma.c (struct def_pragma_macro_value): New.
index 4a8f409..bfc0d43 100644 (file)
@@ -77,7 +77,7 @@ case $build in
     build_xm_file=i386/xm-cygwin.h
     build_exeext=.exe
     ;;
-  i[34567]86-*-mingw32*)
+  i[34567]86-*-mingw32* | x86_64-*-mingw*)
     build_xm_file=i386/xm-mingw32.h
     build_exeext=.exe
     ;;
index d1deffc..7cf3299 100644 (file)
@@ -1343,7 +1343,7 @@ i[34567]86-*-pe | i[34567]86-*-cygwin*)
                thread_file='posix'
        fi
        ;;
-i[34567]86-*-mingw32*)
+i[34567]86-*-mingw32* | x86_64-*-mingw32*)
        tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/mingw32.h"
        xm_file=i386/xm-mingw32.h
        tmake_file="i386/t-cygming i386/t-mingw32"
index 8e6119b..150a433 100644 (file)
@@ -168,7 +168,7 @@ case ${host} in
     host_xmake_file="${host_xmake_file} i386/x-cygwin"
     host_exeext=.exe
     ;;
-  i[34567]86-*-mingw32*)
+  i[34567]86-*-mingw32* | x86_64-*-mingw*)
     host_xm_file=i386/xm-mingw32.h
     host_xmake_file="${host_xmake_file} i386/x-mingw32"
     host_exeext=.exe
index aa4ca2a..f7e8feb 100644 (file)
@@ -21,18 +21,35 @@ along with GCC; see the file COPYING.  If not, write to
 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
 Boston, MA 02110-1301, USA.  */
 
+#if TARGET_64BIT_DEFAULT
+#ifndef DWARF2_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
+#endif
+#ifndef DWARF2_UNWIND_INFO
+#define DWARF2_UNWIND_INFO 1
+#endif
+#endif
+
 #define DBX_DEBUGGING_INFO 1
 #define SDB_DEBUGGING_INFO 1
 #undef PREFERRED_DEBUGGING_TYPE
+#if TARGET_64BIT_DEFAULT
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+#else
 #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+#endif
+
+#undef TARGET_64BIT_MS_ABI
+#define TARGET_64BIT_MS_ABI TARGET_64BIT
 
 #ifdef HAVE_GAS_PE_SECREL32_RELOC
 #define DWARF2_DEBUGGING_INFO 1
 
 #undef DBX_REGISTER_NUMBER
-#define DBX_REGISTER_NUMBER(n) (write_symbols == DWARF2_DEBUG   \
-                                ? svr4_dbx_register_map[n]      \
-                                : dbx_register_map[n])
+#define DBX_REGISTER_NUMBER(n)                         \
+  (TARGET_64BIT ? dbx64_register_map[n]                        \
+   : (write_symbols == DWARF2_DEBUG                    \
+      ? svr4_dbx_register_map[n] : dbx_register_map[n]))
 
 /* Use section relative relocations for debugging offsets.  Unlike
    other targets that fake this by putting the section VMA at 0, PE
@@ -97,14 +114,32 @@ Boston, MA 02110-1301, USA.  */
 #undef MATH_LIBRARY
 #define MATH_LIBRARY ""
 
-#define SIZE_TYPE "unsigned int"
-#define PTRDIFF_TYPE "int"
+#define SIZE_TYPE (TARGET_64BIT ? "long long unsigned int" : "unsigned int")
+#define PTRDIFF_TYPE (TARGET_64BIT ? "long long int" : "int")
+
 #define WCHAR_TYPE_SIZE 16
 #define WCHAR_TYPE "short unsigned int"
 
+/* Windows64 continues to use a 32-bit long type.  */
+#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 (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 */
+#define HANDLE_PRAGMA_PUSH_POP_MACRO 1
 
 union tree_node;
 #define TREE union tree_node *
@@ -166,19 +201,21 @@ do {                                                      \
 } while (0)
 
 \f
-/* Emit code to check the stack when allocating more that 4000
+/* Emit code to check the stack when allocating more than 4000
    bytes in one go.  */
-
 #define CHECK_STACK_LIMIT 4000
 
+#undef STACK_BOUNDARY
+#define STACK_BOUNDARY (TARGET_64BIT_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.
    We also align doubles to 64-bits for MSVC default compatibility.  */
 
 #undef TARGET_SUBTARGET_DEFAULT
 #define TARGET_SUBTARGET_DEFAULT \
-   (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE \
-    | MASK_ALIGN_DOUBLE)
+       (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS \
+        | MASK_STACK_PROBE | MASK_ALIGN_DOUBLE)
 
 /* This is how to output an assembler line
    that says to advance the location counter
@@ -245,7 +282,9 @@ do {                                                        \
 /* DWARF2 Unwinding doesn't work with exception handling yet.  To make
    it work, we need to build a libgcc_s.dll, and dcrt0.o should be
    changed to call __register_frame_info/__deregister_frame_info.  */
+#ifndef DWARF2_UNWIND_INFO
 #define DWARF2_UNWIND_INFO 0
+#endif
 
 /* Don't assume anything about the header files.  */
 #define NO_IMPLICIT_EXTERN_C
@@ -346,8 +385,8 @@ do {                                                        \
 #define TARGET_USE_LOCAL_THUNK_ALIAS_P(DECL) (!DECL_ONE_ONLY (DECL))
 
 #define SUBTARGET_ATTRIBUTE_TABLE \
-  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ \
   { "selectany", 0, 0, true, false, false, ix86_handle_selectany_attribute }
+  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
 
 /*  mcount() does not need a counter variable.  */
 #undef NO_PROFILE_COUNTERS
index 5b65689..371feae 100644 (file)
 
        .global ___chkstk
        .global __alloca
+#ifndef _WIN64
 ___chkstk:
 __alloca:
-       pushl  %ecx             /* save temp */
-       movl   %esp,%ecx        /* get sp */
-       addl   $0x8,%ecx        /* and point to return addr */
+       pushl   %ecx            /* save temp */
+       leal    8(%esp), %ecx   /* point past return addr */
+       cmpl    $0x1000, %eax   /* > 4k ?*/
+       jb      Ldone
 
-probe:         cmpl   $0x1000,%eax     /* > 4k ?*/
-       jb    done              
+Lprobe:
+       subl    $0x1000, %ecx           /* yes, move pointer down 4k*/
+       orl     $0x0, (%ecx)            /* probe there */
+       subl    $0x1000, %eax           /* decrement count */
+       cmpl    $0x1000, %eax
+       ja      Lprobe                  /* and do it again */
 
-       subl   $0x1000,%ecx             /* yes, move pointer down 4k*/
-       orl    $0x0,(%ecx)              /* probe there */
-       subl   $0x1000,%eax             /* decrement count */
-       jmp    probe                    /* and do it again */
+Ldone:
+       subl    %eax, %ecx         
+       orl     $0x0, (%ecx)    /* less than 4k, just peek here */
 
-done:  subl   %eax,%ecx           
-       orl    $0x0,(%ecx)      /* less that 4k, just peek here */
+       movl    %esp, %eax      /* save old stack pointer */
+       movl    %ecx, %esp      /* decrement stack */
+       movl    (%eax), %ecx    /* recover saved temp */
+       movl    4(%eax), %eax   /* recover return address */
 
-       movl   %esp,%eax
-       movl   %ecx,%esp        /* decrement stack */
+       /* Push the return value back.  Doing this instead of just
+          jumping to %eax preserves the cached call-return stack
+          used by most modern processors.  */
+       pushl   %eax
+       ret
+#else
+/* __alloca is a normal function call, which uses %rcx as the argument.  */
+__alloca:
+       movq    %rcx, %rax
+       /* FALLTHRU */
+
+/* ___chkstk is a *special* function call, which uses %rax as the argument.
+   We avoid clobbering the 4 integer argument registers, %rcx, %rdx, 
+   %r8 and %r9, which leaves us with %rax, %r10, and %r11 to use.  */
+___chkstk:
+       popq    %r11            /* pop return address */
+       movq    %rsp, %r10      /* get sp */
+       cmpq    $0x1000, %rax   /* > 4k ?*/
+       jb      Ldone
 
-       movl   (%eax),%ecx      /* recover saved temp */
-       movl   4(%eax),%eax     /* get return address */
-       jmp    *%eax    
+Lprobe:
+       subq    $0x1000, %r10           /* yes, move pointer down 4k*/
+       orl     $0x0, (%r10)            /* probe there */
+       subq    $0x1000, %rax           /* decrement count */
+       cmpq    $0x1000, %rax
+       ja      Lprobe                  /* and do it again */
+
+Ldone:
+       subq    %rax, %r10
+       orl     $0x0, (%r10)    /* less than 4k, just peek here */
+       movq    %r10, %rsp      /* decrement stack */
+
+       /* Push the return value back.  Doing this instead of just
+          jumping to %r11 preserves the cached call-return stack
+          used by most modern processors.  */
+       pushq   %r11
+       ret
+#endif
 #endif
index d13b539..c87a771 100644 (file)
@@ -102,7 +102,8 @@ __gthr_win32_once (__gthread_once_t *once, void (*func) (void))
    C++ EH. Mingw uses a thread-support DLL to work-around this problem.  */
 
 int
-__gthr_win32_key_create (__gthread_key_t *key, void (*dtor) (void *))
+__gthr_win32_key_create (__gthread_key_t *key,
+                        void (*dtor) (void *) __attribute__((unused)))
 {
   int status = 0;
   DWORD tls_index = TlsAlloc ();
index ed25402..7106e87 100644 (file)
@@ -1308,9 +1308,15 @@ static int const x86_64_int_parameter_registers[6] =
   FIRST_REX_INT_REG /*R8 */, FIRST_REX_INT_REG + 1 /*R9 */
 };
 
+static int const x86_64_ms_abi_int_parameter_registers[4] =
+{
+  2 /*RCX*/, 1 /*RDX*/,
+  FIRST_REX_INT_REG /*R8 */, FIRST_REX_INT_REG + 1 /*R9 */
+};
+
 static int const x86_64_int_return_registers[4] =
 {
-  0 /*RAX*/, 1 /*RDI*/, 5 /*RDI*/, 4 /*RSI*/
+  0 /*RAX*/, 1 /*RDX*/, 5 /*RDI*/, 4 /*RSI*/
 };
 
 /* The "default" register map used in 64bit mode.  */
@@ -1857,9 +1863,16 @@ override_options (void)
     }
   else
     {
-      ix86_cmodel = CM_32;
-      if (TARGET_64BIT)
+      /* For TARGET_64BIT_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)
+       ix86_cmodel = CM_SMALL_PIC, flag_pic = 1;
+      else if (TARGET_64BIT)
        ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
+      else
+        ix86_cmodel = CM_32;
     }
   if (ix86_asm_string != 0)
     {
@@ -1981,15 +1994,16 @@ override_options (void)
   /* Validate -mregparm= value.  */
   if (ix86_regparm_string)
     {
+      if (TARGET_64BIT)
+       warning (0, "-mregparm is ignored in 64-bit mode");
       i = atoi (ix86_regparm_string);
       if (i < 0 || i > REGPARM_MAX)
        error ("-mregparm=%d is not between 0 and %d", i, REGPARM_MAX);
       else
        ix86_regparm = i;
     }
-  else
-   if (TARGET_64BIT)
-     ix86_regparm = REGPARM_MAX;
+  if (TARGET_64BIT)
+    ix86_regparm = REGPARM_MAX;
 
   /* If the user has provided any of the -malign-* options,
      warn and use that value only if -falign-* is not set.
@@ -2135,18 +2149,16 @@ override_options (void)
 
   if (TARGET_64BIT)
     {
-      if (TARGET_ALIGN_DOUBLE)
-       error ("-malign-double makes no sense in the 64bit mode");
       if (TARGET_RTD)
-       error ("-mrtd calling convention not supported in the 64bit mode");
+       warning (0, "-mrtd is ignored in 64bit mode");
 
       /* Enable by default the SSE and MMX builtins.  Do allow the user to
         explicitly disable any of these.  In particular, disabling SSE and
         MMX for kernel code is extremely useful.  */
       target_flags
-       |= ((MASK_SSE2 | MASK_SSE | MASK_MMX | MASK_128BIT_LONG_DOUBLE)
+       |= ((MASK_SSE2 | MASK_SSE | MASK_MMX | TARGET_SUBTARGET64_DEFAULT)
            & ~target_flags_explicit);
-     }
+    }
   else
     {
       /* i386 ABI does not specify red zone.  It still makes sense to use it
@@ -2644,8 +2656,10 @@ ix86_handle_cconv_attribute (tree *node, tree name,
 
   if (TARGET_64BIT)
     {
-      warning (OPT_Wattributes, "%qs attribute ignored",
-              IDENTIFIER_POINTER (name));
+      /* Do not warn when emulating the MS ABI.  */
+      if (!TARGET_64BIT_MS_ABI)
+       warning (OPT_Wattributes, "%qs attribute ignored",
+                IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
       return NULL_TREE;
     }
@@ -2932,6 +2946,7 @@ bool
 ix86_function_arg_regno_p (int regno)
 {
   int i;
+  const int *parm_regs;
 
   if (!TARGET_64BIT)
     {
@@ -2959,11 +2974,15 @@ ix86_function_arg_regno_p (int regno)
     }
 
   /* RAX is used as hidden argument to va_arg functions.  */
-  if (regno == 0)
+  if (!TARGET_64BIT_MS_ABI && regno == 0)
     return true;
 
+  if (TARGET_64BIT_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++)
-    if (regno == x86_64_int_parameter_registers[i])
+    if (regno == parm_regs[i])
       return true;
   return false;
 }
@@ -3741,6 +3760,21 @@ function_arg_advance_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
     cum->words += words;
 }
 
+static void
+function_arg_advance_ms_64 (CUMULATIVE_ARGS *cum, HOST_WIDE_INT bytes,
+                           HOST_WIDE_INT words)
+{
+  /* Otherwise, this should be passed indirect.  */
+  gcc_assert (bytes == 1 || bytes == 2 || bytes == 4 || bytes == 8);
+
+  cum->words += words;
+  if (cum->nregs > 0)
+    {
+      cum->nregs -= 1;
+      cum->regno += 1;
+    }
+}
+
 void
 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
                      tree type, int named ATTRIBUTE_UNUSED)
@@ -3756,7 +3790,9 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
   if (type)
     mode = type_natural_mode (type);
 
-  if (TARGET_64BIT)
+  if (TARGET_64BIT_MS_ABI)
+    function_arg_advance_ms_64 (cum, bytes, words);
+  else if (TARGET_64BIT)
     function_arg_advance_64 (cum, mode, type, words);
   else
     function_arg_advance_32 (cum, mode, type, bytes, words);
@@ -3887,9 +3923,47 @@ function_arg_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
                              cum->sse_regno);
 }
 
+static rtx
+function_arg_ms_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+                   enum machine_mode orig_mode, int named)
+{
+  unsigned int regno;
+
+  /* Avoid the AL settings for the Unix64 ABI.  */
+  if (mode == VOIDmode)
+    return constm1_rtx;
+
+  /* If we've run out of registers, it goes on the stack.  */
+  if (cum->nregs == 0)
+    return NULL_RTX;
+
+  regno = x86_64_ms_abi_int_parameter_registers[cum->regno];
+
+  /* Only floating point modes are passed in anything but integer regs.  */
+  if (TARGET_SSE && (mode == SFmode || mode == DFmode))
+    {
+      if (named)
+       regno = cum->regno + FIRST_SSE_REG;
+      else
+       {
+         rtx t1, t2;
+
+         /* Unnamed floating parameters are passed in both the
+            SSE and integer registers.  */
+         t1 = gen_rtx_REG (mode, cum->regno + FIRST_SSE_REG);
+         t2 = gen_rtx_REG (mode, regno);
+         t1 = gen_rtx_EXPR_LIST (VOIDmode, t1, const0_rtx);
+         t2 = gen_rtx_EXPR_LIST (VOIDmode, t2, const0_rtx);
+         return gen_rtx_PARALLEL (mode, gen_rtvec (2, t1, t2));
+       }
+    }
+
+  return gen_reg_or_parallel (mode, orig_mode, regno);
+}
+
 rtx
 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode,
-             tree type, int named ATTRIBUTE_UNUSED)
+             tree type, int named)
 {
   enum machine_mode mode = omode;
   HOST_WIDE_INT bytes, words;
@@ -3905,7 +3979,9 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode,
   if (type && TREE_CODE (type) == VECTOR_TYPE)
     mode = type_natural_mode (type);
 
-  if (TARGET_64BIT)
+  if (TARGET_64BIT_MS_ABI)
+    return function_arg_ms_64 (cum, mode, omode, named);
+  else if (TARGET_64BIT)
     return function_arg_64 (cum, mode, omode, type);
   else
     return function_arg_32 (cum, mode, omode, type, bytes, words);
@@ -3922,7 +3998,30 @@ ix86_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
                        enum machine_mode mode ATTRIBUTE_UNUSED,
                        tree type, bool named ATTRIBUTE_UNUSED)
 {
-  if (TARGET_64BIT && type && int_size_in_bytes (type) == -1)
+  if (TARGET_64BIT_MS_ABI)
+    {
+      if (type)
+       {
+         /* Arrays are passed by reference.  */
+         if (TREE_CODE (type) == ARRAY_TYPE)
+           return true;
+
+         if (AGGREGATE_TYPE_P (type))
+           {
+             /* Structs/unions of sizes other than 8, 16, 32, or 64 bits
+                are passed by reference.  */
+             int el2 = exact_log2 (int_size_in_bytes (type));
+             return !(el2 >= 0 && el2 <= 3);
+           }
+       }
+
+      /* __m128 is passed by reference.  */
+      /* ??? How to handle complex?  For now treat them as structs,
+        and pass them by reference if they're too large.  */
+      if (GET_MODE_SIZE (mode) > 8)
+       return true;
+    }
+  else if (TARGET_64BIT && type && int_size_in_bytes (type) == -1)
     return 1;
 
   return 0;
@@ -4025,6 +4124,8 @@ ix86_function_value_regno_p (int regno)
       return true;
 
     case FIRST_FLOAT_REG:
+      if (TARGET_64BIT_MS_ABI)
+       return false;
       return TARGET_FLOAT_RETURNS_IN_80387;
 
     case FIRST_SSE_REG:
@@ -4132,6 +4233,22 @@ function_value_64 (enum machine_mode orig_mode, enum machine_mode mode,
 }
 
 static rtx
+function_value_ms_64 (enum machine_mode orig_mode, enum machine_mode mode)
+{
+  unsigned int regno = 0;
+
+  if (TARGET_SSE)
+    {
+      if (mode == SFmode || mode == DFmode)
+       regno = FIRST_SSE_REG;
+      else if (VECTOR_MODE_P (mode) || GET_MODE_SIZE (mode) == 16)
+       regno = FIRST_SSE_REG;
+    }
+
+  return gen_rtx_REG (orig_mode, regno);
+}
+
+static rtx
 ix86_function_value_1 (tree valtype, tree fntype_or_decl,
                       enum machine_mode orig_mode, enum machine_mode mode)
 {
@@ -4142,7 +4259,9 @@ ix86_function_value_1 (tree valtype, tree fntype_or_decl,
     fn = fntype_or_decl;
   fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
 
-  if (TARGET_64BIT)
+  if (TARGET_64BIT_MS_ABI)
+    return function_value_ms_64 (orig_mode, mode);
+  else if (TARGET_64BIT)
     return function_value_64 (orig_mode, mode, valtype);
   else
     return function_value_32 (orig_mode, mode, fntype, fn);
@@ -4214,12 +4333,27 @@ return_in_memory_64 (tree type, enum machine_mode mode)
   return !examine_argument (mode, type, 1, &needed_intregs, &needed_sseregs);
 }
 
+static int
+return_in_memory_ms_64 (tree type, enum machine_mode mode)
+{
+  HOST_WIDE_INT size = int_size_in_bytes (type);
+
+  /* __m128 and friends are returned in xmm0.  */
+  if (size == 16 && VECTOR_MODE_P (mode))
+    return 0;
+
+  /* Otherwise, the size must be exactly in [1248].  */
+  return (size != 1 && size != 2 && size != 4 && size != 8);
+}
+
 int
 ix86_return_in_memory (tree type)
 {
   enum machine_mode mode = type_natural_mode (type);
 
-  if (TARGET_64BIT)
+  if (TARGET_64BIT_MS_ABI)
+    return return_in_memory_ms_64 (type, mode);
+  else if (TARGET_64BIT)
     return return_in_memory_64 (type, mode);
   else
     return return_in_memory_32 (type, mode);
@@ -4280,7 +4414,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)
+  if (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
     return build_pointer_type (char_type_node);
 
   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
@@ -4400,6 +4534,27 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
 }
 
 static void
+setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
+{
+  int set = get_varargs_alias_set ();
+  int i;
+
+  for (i = cum->regno; i < REGPARM_MAX; i++)
+    {
+      rtx reg, mem;
+
+      mem = gen_rtx_MEM (Pmode,
+                        plus_constant (virtual_incoming_args_rtx,
+                                       i * UNITS_PER_WORD));
+      MEM_NOTRAP_P (mem) = 1;
+      set_mem_alias_set (mem, set);
+
+      reg = gen_rtx_REG (Pmode, x86_64_ms_abi_int_parameter_registers[i]);
+      emit_move_insn (mem, reg);
+    }
+}
+
+static void
 ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
                             tree type, int *pretend_size ATTRIBUTE_UNUSED,
                             int no_rtl)
@@ -4426,7 +4581,10 @@ ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
   if (stdarg_p)
     function_arg_advance (&next_cum, mode, type, 1);
 
-  setup_incoming_varargs_64 (&next_cum);
+  if (TARGET_64BIT_MS_ABI)
+    setup_incoming_varargs_ms_64 (&next_cum);
+  else
+    setup_incoming_varargs_64 (&next_cum);
 }
 
 /* Implement va_start.  */
@@ -4440,7 +4598,7 @@ ix86_va_start (tree valist, rtx nextarg)
   tree type;
 
   /* Only 64bit target needs something special.  */
-  if (!TARGET_64BIT)
+  if (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
     {
       std_expand_builtin_va_start (valist, nextarg);
       return;
@@ -4519,7 +4677,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)
+  if (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
 
   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
@@ -5711,21 +5869,30 @@ ix86_expand_prologue (void)
   else
     {
       /* Only valid for Win32.  */
-      rtx eax = gen_rtx_REG (SImode, 0);
-      bool eax_live = ix86_eax_live_at_start_p ();
+      rtx eax = gen_rtx_REG (Pmode, 0);
+      bool eax_live;
       rtx t;
 
-      gcc_assert (!TARGET_64BIT);
+      gcc_assert (!TARGET_64BIT || TARGET_64BIT_MS_ABI);
+
+      if (TARGET_64BIT_MS_ABI)
+       eax_live = false;
+      else
+       eax_live = ix86_eax_live_at_start_p ();
 
       if (eax_live)
        {
          emit_insn (gen_push (eax));
-         allocate -= 4;
+         allocate -= UNITS_PER_WORD;
        }
 
       emit_move_insn (eax, GEN_INT (allocate));
 
-      insn = emit_insn (gen_allocate_stack_worker (eax));
+      if (TARGET_64BIT)
+       insn = gen_allocate_stack_worker_64 (eax);
+      else
+       insn = gen_allocate_stack_worker_32 (eax);
+      insn = emit_insn (insn);
       RTX_FRAME_RELATED_P (insn) = 1;
       t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-allocate));
       t = gen_rtx_SET (VOIDmode, stack_pointer_rtx, t);
@@ -5741,7 +5908,7 @@ ix86_expand_prologue (void)
                               - frame.nregs * UNITS_PER_WORD);
          else
            t = plus_constant (stack_pointer_rtx, allocate);
-         emit_move_insn (eax, gen_rtx_MEM (SImode, t));
+         emit_move_insn (eax, gen_rtx_MEM (Pmode, t));
        }
     }
 
@@ -5995,7 +6162,7 @@ ix86_expand_epilogue (int style)
        {
          rtx ecx = gen_rtx_REG (SImode, 2);
 
-         /* There is no "pascal" calling convention in 64bit ABI.  */
+         /* There is no "pascal" calling convention in any 64bit ABI.  */
          gcc_assert (!TARGET_64BIT);
 
          emit_insn (gen_popsi1 (ecx));
@@ -6848,7 +7015,8 @@ legitimize_pic_address (rtx orig, rtx reg)
        addr = XEXP (addr, 0);
       if (GET_CODE (addr) == PLUS)
          {
-            new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)), UNSPEC_GOTOFF);
+            new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
+                                 UNSPEC_GOTOFF);
            new = gen_rtx_PLUS (Pmode, new, XEXP (addr, 1));
          }
        else
@@ -6879,7 +7047,8 @@ legitimize_pic_address (rtx orig, rtx reg)
        addr = XEXP (addr, 0);
       if (GET_CODE (addr) == PLUS)
          {
-            new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)), UNSPEC_GOTOFF);
+            new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
+                                 UNSPEC_GOTOFF);
            new = gen_rtx_PLUS (Pmode, new, XEXP (addr, 1));
          }
        else
@@ -6898,6 +7067,11 @@ legitimize_pic_address (rtx orig, rtx reg)
              see gotoff_operand.  */
           || (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF))
     {
+      /* 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);
+
       if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
        {
          new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTPCREL);
@@ -7505,7 +7679,8 @@ output_pic_addr_const (FILE *file, rtx x, int code)
        {
          const char *name = XSTR (x, 0);
 
-         /* Mark the decl as referenced so that cgraph will output the function.  */
+         /* Mark the decl as referenced so that cgraph will
+            output the function.  */
          if (SYMBOL_REF_DECL (x))
            mark_decl_referenced (SYMBOL_REF_DECL (x));
 
@@ -7516,7 +7691,8 @@ output_pic_addr_const (FILE *file, rtx x, int code)
 #endif
          assemble_name (file, name);
        }
-      if (!TARGET_MACHO && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
+      if (!TARGET_MACHO && !TARGET_64BIT_MS_ABI
+         && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
        fputs ("@PLT", file);
       break;
 
@@ -9291,7 +9467,6 @@ ix86_expand_clear (rtx dest)
   /* Avoid HImode and its attendant prefix byte.  */
   if (GET_MODE_SIZE (GET_MODE (dest)) < 4)
     dest = gen_rtx_REG (SImode, REGNO (dest));
-
   tmp = gen_rtx_SET (VOIDmode, dest, const0_rtx);
 
   /* This predicate should match that for movsi_xor and movdi_xor_rex64.  */
@@ -19508,37 +19683,29 @@ static rtx
 x86_this_parameter (tree function)
 {
   tree type = TREE_TYPE (function);
+  bool aggr = aggregate_value_p (TREE_TYPE (type), type) != 0;
 
   if (TARGET_64BIT)
     {
-      int n = aggregate_value_p (TREE_TYPE (type), type) != 0;
-      return gen_rtx_REG (DImode, x86_64_int_parameter_registers[n]);
+      const int *parm_regs;
+
+      if (TARGET_64BIT_MS_ABI)
+        parm_regs = x86_64_ms_abi_int_parameter_registers;
+      else
+        parm_regs = x86_64_int_parameter_registers;
+      return gen_rtx_REG (DImode, parm_regs[aggr]);
     }
 
-  if (ix86_function_regparm (type, function) > 0)
+  if (ix86_function_regparm (type, function) > 0
+      && !type_has_variadic_args_p (type))
     {
-      tree parm;
-
-      parm = TYPE_ARG_TYPES (type);
-      /* Figure out whether or not the function has a variable number of
-        arguments.  */
-      for (; parm; parm = TREE_CHAIN (parm))
-       if (TREE_VALUE (parm) == void_type_node)
-         break;
-      /* If not, the this parameter is in the first argument.  */
-      if (parm)
-       {
-         int regno = 0;
-         if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
-           regno = 2;
-         return gen_rtx_REG (SImode, regno);
-       }
+      int regno = 0;
+      if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
+       regno = 2;
+      return gen_rtx_REG (SImode, regno);
     }
 
-  if (aggregate_value_p (TREE_TYPE (type), type))
-    return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8));
-  else
-    return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4));
+  return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, aggr ? 8 : 4));
 }
 
 /* Determine whether x86_output_mi_thunk can succeed.  */
@@ -19627,7 +19794,7 @@ x86_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED,
        {
          int tmp_regno = 2 /* ECX */;
          if (lookup_attribute ("fastcall",
-             TYPE_ATTRIBUTES (TREE_TYPE (function))))
+                               TYPE_ATTRIBUTES (TREE_TYPE (function))))
            tmp_regno = 0 /* EAX */;
          tmp = gen_rtx_REG (SImode, tmp_regno);
        }
@@ -19669,6 +19836,10 @@ x86_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED,
     {
       if (!flag_pic || (*targetm.binds_local_p) (function))
        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)
+       gcc_unreachable ();
       else
        {
          tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xops[0]), UNSPEC_GOTPCREL);
@@ -19745,20 +19916,16 @@ void
 x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
 {
   if (TARGET_64BIT)
-    if (flag_pic)
-      {
+    {
 #ifndef NO_PROFILE_COUNTERS
-       fprintf (file, "\tleaq\t%sP%d@(%%rip),%%r11\n", LPREFIX, labelno);
+      fprintf (file, "\tleaq\t%sP%d@(%%rip),%%r11\n", LPREFIX, labelno);
 #endif
+
+      if (!TARGET_64BIT_MS_ABI && flag_pic)
        fprintf (file, "\tcall\t*%s@GOTPCREL(%%rip)\n", MCOUNT_NAME);
-      }
-    else
-      {
-#ifndef NO_PROFILE_COUNTERS
-       fprintf (file, "\tmovq\t$%sP%d,%%r11\n", LPREFIX, labelno);
-#endif
+      else
        fprintf (file, "\tcall\t%s\n", MCOUNT_NAME);
-      }
+    }
   else if (flag_pic)
     {
 #ifndef NO_PROFILE_COUNTERS
@@ -21817,6 +21984,8 @@ static const struct attribute_spec ix86_attribute_table[] =
 #define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
 #undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
 #define TARGET_DWARF_HANDLE_FRAME_UNSPEC ix86_dwarf_handle_frame_unspec
+#undef TARGET_STRICT_ARGUMENT_NAMING
+#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
 
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
index 045741b..e86bb72 100644 (file)
@@ -20,6 +20,21 @@ along with GCC; see the file COPYING.  If not, write to
 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
 Boston, MA 02110-1301, USA.  */
 
+/* The purpose of this file is to define the characteristics of the i386,
+   independent of assembler syntax or operating system.
+
+   Three other files build on this one to describe a specific assembler syntax:
+   bsd386.h, att386.h, and sun386.h.
+
+   The actual tm.h file for a particular system should include
+   this file, and then the file for the appropriate assembler syntax.
+
+   Many macros that specify assembler syntax are omitted entirely from
+   this file because they really belong in the files for particular
+   assemblers.  These include RP, IP, LPREFIX, PUT_OP_SIZE, USE_STAR,
+   ADDR_BEG, ADDR_END, PRINT_IREG, PRINT_SCALE, PRINT_B_I_S, and many
+   that start with ASM_ or end in ASM_OP.  */
+
 #include "config/vxworks-dummy.h"
 
 /* Algorithm to expand string function with.  */
@@ -34,7 +49,9 @@ enum stringop_alg
    loop,
    unrolled_loop
 };
+
 #define NAX_STRINGOP_ALGS 4
+
 /* Specify what algorithm to use for stringops on known size.
    When size is unknown, the UNKNOWN_SIZE alg is used.  When size is
    known at compile time or estimated via feedback, the SIZE array
@@ -43,8 +60,7 @@ enum stringop_alg
    For example initializer:
     {{256, loop}, {-1, rep_prefix_4_byte}}             
    will use loop for blocks smaller or equal to 256 bytes, rep prefix will
-   be used otherwise.
-*/
+   be used otherwise.  */
 struct stringop_algs
 {
   const enum stringop_alg unknown_size;
@@ -54,21 +70,6 @@ struct stringop_algs
   } size [NAX_STRINGOP_ALGS];
 };
 
-/* The purpose of this file is to define the characteristics of the i386,
-   independent of assembler syntax or operating system.
-
-   Three other files build on this one to describe a specific assembler syntax:
-   bsd386.h, att386.h, and sun386.h.
-
-   The actual tm.h file for a particular system should include
-   this file, and then the file for the appropriate assembler syntax.
-
-   Many macros that specify assembler syntax are omitted entirely from
-   this file because they really belong in the files for particular
-   assemblers.  These include RP, IP, LPREFIX, PUT_OP_SIZE, USE_STAR,
-   ADDR_BEG, ADDR_END, PRINT_IREG, PRINT_SCALE, PRINT_B_I_S, and many
-   that start with ASM_ or end in ASM_OP.  */
-
 /* Define the specific costs for a given cpu */
 
 struct processor_costs {
@@ -372,11 +373,17 @@ extern int x86_prefetch_sse;
    the frame pointer in leaf functions.  */
 #define TARGET_DEFAULT 0
 
+/* Extra bits to force on w/ 64-bit mode.  */
+#define TARGET_SUBTARGET64_DEFAULT 0
+
 /* This is not really a target flag, but is done this way so that
    it's analogous to similar code for Mach-O on PowerPC.  darwin.h
    redefines this to 1.  */
 #define TARGET_MACHO 0
 
+/* Likewise, for the Windows 64-bit ABI.  */
+#define TARGET_64BIT_MS_ABI 0
+
 /* Subtargets may reset this to 1 in order to enable 96-bit long double
    with the rounding mode forced to 53 bits.  */
 #define TARGET_96_ROUND_53_LONG_DOUBLE 0
@@ -998,6 +1005,11 @@ 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
index fddd1c2..2fc4f5f 100644 (file)
   [(set_attr "type" "alu,lea")
    (set_attr "mode" "DI")])
 
-(define_expand "allocate_stack_worker"
-  [(match_operand:SI 0 "register_operand" "")]
-  "TARGET_STACK_PROBE"
-{
-  if (reload_completed)
-    {
-      if (TARGET_64BIT)
-       emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
-      else
-       emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
-    }
-  else
-    {
-      if (TARGET_64BIT)
-       emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
-      else
-       emit_insn (gen_allocate_stack_worker_1 (operands[0]));
-    }
-  DONE;
-})
-
-(define_insn "allocate_stack_worker_1"
-  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
-    UNSPECV_STACK_PROBE)
+(define_insn "allocate_stack_worker_32"
+  [(set (match_operand:SI 0 "register_operand" "+a")
+       (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
-   (clobber (match_scratch:SI 1 "=0"))
    (clobber (reg:CC FLAGS_REG))]
   "!TARGET_64BIT && TARGET_STACK_PROBE"
   "call\t__alloca"
   [(set_attr "type" "multi")
    (set_attr "length" "5")])
 
-(define_expand "allocate_stack_worker_postreload"
-  [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
-                                   UNSPECV_STACK_PROBE)
-             (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
-             (clobber (match_dup 0))
-             (clobber (reg:CC FLAGS_REG))])]
-  ""
-  "")
-
-(define_insn "allocate_stack_worker_rex64"
-  [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
-    UNSPECV_STACK_PROBE)
+(define_insn "allocate_stack_worker_64"
+  [(set (match_operand:DI 0 "register_operand" "=a")
+       (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
-   (clobber (match_scratch:DI 1 "=0"))
+   (clobber (reg:DI R10_REG))
+   (clobber (reg:DI R11_REG))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && TARGET_STACK_PROBE"
-  "call\t__alloca"
+  "call\t___chkstk"
   [(set_attr "type" "multi")
    (set_attr "length" "5")])
 
-(define_expand "allocate_stack_worker_rex64_postreload"
-  [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
-                                   UNSPECV_STACK_PROBE)
-             (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
-             (clobber (match_dup 0))
-             (clobber (reg:CC FLAGS_REG))])]
-  ""
-  "")
-
 (define_expand "allocate_stack"
-  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
-                  (minus:SI (reg:SI SP_REG)
-                            (match_operand:SI 1 "general_operand" "")))
-             (clobber (reg:CC FLAGS_REG))])
-   (parallel [(set (reg:SI SP_REG)
-                  (minus:SI (reg:SI SP_REG) (match_dup 1)))
-             (clobber (reg:CC FLAGS_REG))])]
+  [(match_operand 0 "register_operand" "")
+   (match_operand 1 "general_operand" "")]
   "TARGET_STACK_PROBE"
 {
-#ifdef CHECK_STACK_LIMIT
-  if (CONST_INT_P (operands[1])
+  rtx x;
+
+#ifndef CHECK_STACK_LIMIT
+#define CHECK_STACK_LIMIT 0
+#endif
+
+  if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
-    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
-                          operands[1]));
+    {
+      x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
+                              stack_pointer_rtx, 0, OPTAB_DIRECT);
+      if (x != stack_pointer_rtx)
+       emit_move_insn (stack_pointer_rtx, x);
+    }
   else
-#endif
-    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
-                                                           operands[1])));
+    {
+      x = copy_to_mode_reg (Pmode, operands[1]);
+      if (TARGET_64BIT)
+       x = gen_allocate_stack_worker_64 (x);
+      else
+       x = gen_allocate_stack_worker_32 (x);
+      emit_insn (x);
+    }
 
   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
   DONE;
index d99fe62..15078cc 100644 (file)
@@ -27,11 +27,6 @@ Boston, MA 02110-1301, USA.  */
 
 #define TARGET_VERSION fprintf (stderr, " (i386 bare ELF target)");
 
-/* By default, target has a 80387, uses IEEE compatible arithmetic,
-   and returns float values in the 387.  */
-
-#define TARGET_SUBTARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
-
 /* The ELF ABI for the i386 says that records and unions are returned
    in memory.  */
 
index 28c2fb9..c608826 100644 (file)
@@ -21,7 +21,11 @@ the Free Software Foundation, 51 Franklin Street, Fifth Floor,
 Boston, MA 02110-1301, USA.  */
 
 #undef TARGET_VERSION
-#define TARGET_VERSION fprintf (stderr, " (x86 MinGW)"); 
+#if TARGET_64BIT_DEFAULT
+#define TARGET_VERSION fprintf (stderr,"(x86_64 MinGW");
+#else
+#define TARGET_VERSION fprintf (stderr," (x86 MinGW)");
+#endif
 
 /* See i386/crtdll.h for an alternative definition.  */
 #define EXTRA_OS_CPP_BUILTINS()                                        \
@@ -32,13 +36,28 @@ Boston, MA 02110-1301, USA.  */
       builtin_define ("_WIN32");                               \
       builtin_define_std ("WIN32");                            \
       builtin_define_std ("WINNT");                            \
+      if (TARGET_64BIT_MS_ABI)                                 \
+       {                                                       \
+         builtin_define ("__MINGW64__");                       \
+         builtin_define_with_value("_INTEGRAL_MAX_BITS","64",0); \
+         builtin_define_std ("WIN64");                         \
+         builtin_define_std ("_WIN64");                        \
+       }                                                       \
+      else                                                     \
+       {                                                       \
+         builtin_define_with_value("_INTEGRAL_MAX_BITS","32",0); \
+       }                                                       \
     }                                                          \
   while (0)
 
 /* Override the standard choice of /usr/include as the default prefix
    to try when searching for header files.  */
 #undef STANDARD_INCLUDE_DIR
+#if TARGET_64BIT_DEFAULT
+#define STANDARD_INCLUDE_DIR "/mingw/include64"
+#else
 #define STANDARD_INCLUDE_DIR "/mingw/include"
+#endif
 #undef STANDARD_INCLUDE_COMPONENT
 #define STANDARD_INCLUDE_COMPONENT "MINGW"
 
@@ -71,8 +90,12 @@ Boston, MA 02110-1301, USA.  */
 
 /* Override startfile prefix defaults.  */
 #ifndef STANDARD_STARTFILE_PREFIX_1
+#if TARGET_64BIT_DEFAULT
+#define STANDARD_STARTFILE_PREFIX_1 "/mingw/lib64/"
+#else
 #define STANDARD_STARTFILE_PREFIX_1 "/mingw/lib/"
 #endif
+#endif
 #ifndef STANDARD_STARTFILE_PREFIX_2
 #define STANDARD_STARTFILE_PREFIX_2 ""
 #endif
index abb4e05..d27fd1c 100644 (file)
@@ -61,5 +61,10 @@ Boston, MA 02110-1301, USA.  */
 
 /* By default, target has a 80387, uses IEEE compatible arithmetic,
    and returns float values in the 387.  */
+#define TARGET_SUBTARGET_DEFAULT \
+       (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
 
-#define TARGET_SUBTARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
+/* By default, 64-bit mode uses 128-bit long double.  */
+#undef TARGET_SUBTARGET64_DEFAULT
+#define TARGET_SUBTARGET64_DEFAULT \
+       MASK_128BIT_LONG_DOUBLE
index a27dccf..80b2b71 100644 (file)
@@ -562,7 +562,8 @@ __gthread_once (__gthread_once_t *once, void (*func) (void))
    leaks, especially in threaded applications making extensive use of
    C++ EH. Mingw uses a thread-support DLL to work-around this problem.  */
 static inline int
-__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
+__gthread_key_create (__gthread_key_t *key,
+                     void (*dtor) (void *) __attribute__((unused)))
 {
   int status = 0;
   DWORD tls_index = TlsAlloc ();
index 4271a40..de59b9d 100644 (file)
@@ -1,3 +1,7 @@
+2007-02-30  Kai Tietz  <kai.tietz@onevision.com>
+
+       * config.host (x86_64-*-mingw*): New target.
+
 2007-03-23  Michael Meissner  <michael.meissner@amd.com>
            H.J. Lu  <hongjiu.lu@intel.com>
 
index 389fec2..f5fff37 100644 (file)
@@ -364,7 +364,7 @@ i[4567]86-wrs-vxworks|i[4567]86-wrs-vxworksae)
        ;;
 i[34567]86-*-pe | i[34567]86-*-cygwin*)
        ;;
-i[34567]86-*-mingw32*)
+i[34567]86-*-mingw32* | x86_64-*-mingw*)
        ;;
 i[34567]86-*-uwin*)
        ;;