This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: revised**2 x86_64-pc-mingw32 patch


Committed as follows.


r~

+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.

--- gcc/config/i386/cygming.h	(revision 123380)
+++ gcc/config/i386/cygming.h	(local)
@@ -21,18 +21,35 @@ along with GCC; see the file COPYING.  I
 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
+
+#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)
 
 /* 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)
 
 
-/* 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
--- gcc/config/i386/cygwin.asm	(revision 123380)
+++ gcc/config/i386/cygwin.asm	(local)
@@ -42,27 +42,66 @@
 
 	.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 */
-
-probe: 	cmpl   $0x1000,%eax	/* > 4k ?*/
-	jb    done		
-
-	subl   $0x1000,%ecx  		/* yes, move pointer down 4k*/
-	orl    $0x0,(%ecx)   		/* probe there */
-	subl   $0x1000,%eax  	 	/* decrement count */
-	jmp    probe           	 	/* and do it again */
-
-done: 	subl   %eax,%ecx	   
-	orl    $0x0,(%ecx)	/* less that 4k, just peek here */
-
-	movl   %esp,%eax
-	movl   %ecx,%esp	/* decrement stack */
-
-	movl   (%eax),%ecx	/* recover saved temp */
-	movl   4(%eax),%eax	/* get return address */
-	jmp    *%eax	
+	pushl	%ecx		/* save temp */
+	leal	8(%esp), %ecx	/* point past return addr */
+	cmpl	$0x1000, %eax	/* > 4k ?*/
+	jb	Ldone
+
+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 */
+
+Ldone:
+	subl	%eax, %ecx	   
+	orl	$0x0, (%ecx)	/* less than 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 */
+
+	/* 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
+
+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
--- gcc/config/i386/gthr-win32.c	(revision 123380)
+++ gcc/config/i386/gthr-win32.c	(local)
@@ -102,7 +102,8 @@ __gthr_win32_once (__gthread_once_t *onc
    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 ();
--- gcc/config/i386/i386.c	(revision 123380)
+++ gcc/config/i386/i386.c	(local)
@@ -1308,9 +1308,15 @@ static int const x86_64_int_parameter_re
   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,
 
   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->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 *c
   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, e
 			      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
   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 
 			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 ori
 }
 
 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, tre
     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 mac
   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_AR
 }
 
 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_
   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 
   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 re
 	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 re
 	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 re
 	      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
 	{
 	  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
 #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 ATTRIBUT
 	{
 	  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 ATTRIBUT
     {
       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_
 #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
--- gcc/config/i386/i386.h	(revision 123380)
+++ gcc/config/i386/i386.h	(local)
@@ -20,6 +20,21 @@ along with GCC; see the file COPYING.  I
 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
--- gcc/config/i386/i386.md	(revision 123380)
+++ gcc/config/i386/i386.md	(local)
@@ -19611,86 +19611,56 @@
   [(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;
--- gcc/config/i386/i386elf.h	(revision 123380)
+++ gcc/config/i386/i386elf.h	(local)
@@ -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.  */
 
--- gcc/config/i386/mingw32.h	(revision 123380)
+++ gcc/config/i386/mingw32.h	(local)
@@ -21,7 +21,11 @@ the Free Software Foundation, 51 Frankli
 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
--- gcc/config/i386/unix.h	(revision 123380)
+++ gcc/config/i386/unix.h	(local)
@@ -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
--- gcc/config.build	(revision 123380)
+++ gcc/config.build	(local)
@@ -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
     ;;
--- gcc/config.gcc	(revision 123380)
+++ gcc/config.gcc	(local)
@@ -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"
--- gcc/config.host	(revision 123380)
+++ gcc/config.host	(local)
@@ -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
--- gcc/gthr-win32.h	(revision 123380)
+++ gcc/gthr-win32.h	(local)
@@ -562,7 +562,8 @@ __gthread_once (__gthread_once_t *once, 
    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 ();
--- libgcc/ChangeLog	(revision 123380)
+++ libgcc/ChangeLog	(local)
@@ -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>
 
--- libgcc/config.host	(revision 123380)
+++ libgcc/config.host	(local)
@@ -364,7 +364,7 @@ i[4567]86-wrs-vxworks|i[4567]86-wrs-vxwo
 	;;
 i[34567]86-*-pe | i[34567]86-*-cygwin*)
 	;;
-i[34567]86-*-mingw32*)
+i[34567]86-*-mingw32* | x86_64-*-mingw*)
 	;;
 i[34567]86-*-uwin*)
 	;;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]