aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/i386
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2007-03-30 14:45:03 -0700
committerRichard Henderson <rth@gcc.gnu.org>2007-03-30 14:45:03 -0700
commitccf8e764e9ca5a530de57cdabdb7123734de2d4a (patch)
tree740f1648846b62e38649ab4639fe02ff63c22ab5 /gcc/config/i386
parent8318b0d99afacde466752a417e0f6c544b15b644 (diff)
downloadgcc-ccf8e764e9ca5a530de57cdabdb7123734de2d4a.zip
gcc-ccf8e764e9ca5a530de57cdabdb7123734de2d4a.tar.gz
gcc-ccf8e764e9ca5a530de57cdabdb7123734de2d4a.tar.bz2
cygming.h (DWARF2_DEBUGGING_INFO): Enable by default for 64-bit.
gcc/ * 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. Co-Authored-By: Kai Tietz <kai.tietz@onevision.com> From-SVN: r123372
Diffstat (limited to 'gcc/config/i386')
-rw-r--r--gcc/config/i386/cygming.h59
-rw-r--r--gcc/config/i386/cygwin.asm71
-rw-r--r--gcc/config/i386/gthr-win32.c3
-rw-r--r--gcc/config/i386/i386.c311
-rw-r--r--gcc/config/i386/i386.h46
-rw-r--r--gcc/config/i386/i386.md94
-rw-r--r--gcc/config/i386/i386elf.h5
-rw-r--r--gcc/config/i386/mingw32.h25
-rw-r--r--gcc/config/i386/unix.h7
9 files changed, 437 insertions, 184 deletions
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index aa4ca2a..f7e8feb 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -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
+
+#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
diff --git a/gcc/config/i386/cygwin.asm b/gcc/config/i386/cygwin.asm
index 5b65689..371feae 100644
--- a/gcc/config/i386/cygwin.asm
+++ b/gcc/config/i386/cygwin.asm
@@ -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 */
+ 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
diff --git a/gcc/config/i386/gthr-win32.c b/gcc/config/i386/gthr-win32.c
index d13b539..c87a771 100644
--- a/gcc/config/i386/gthr-win32.c
+++ b/gcc/config/i386/gthr-win32.c
@@ -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 ();
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index ed25402..7106e87 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 045741b..e86bb72 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index fddd1c2..2fc4f5f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -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;
diff --git a/gcc/config/i386/i386elf.h b/gcc/config/i386/i386elf.h
index d99fe62..15078cc 100644
--- a/gcc/config/i386/i386elf.h
+++ b/gcc/config/i386/i386elf.h
@@ -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. */
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
index 28c2fb9..c608826 100644
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -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
diff --git a/gcc/config/i386/unix.h b/gcc/config/i386/unix.h
index abb4e05..d27fd1c 100644
--- a/gcc/config/i386/unix.h
+++ b/gcc/config/i386/unix.h
@@ -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