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
This commit is contained in:
Richard Henderson 2007-03-30 14:45:03 -07:00 committed by Richard Henderson
parent 8318b0d99a
commit ccf8e764e9
16 changed files with 542 additions and 207 deletions

View File

@ -1,3 +1,80 @@
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> 2007-03-30 Richard Henderson <rth@redhat.com>
Kai Tietz <kai.tietz@onevision.com> Kai Tietz <kai.tietz@onevision.com>

View File

@ -77,7 +77,7 @@ case $build in
build_xm_file=i386/xm-cygwin.h build_xm_file=i386/xm-cygwin.h
build_exeext=.exe build_exeext=.exe
;; ;;
i[34567]86-*-mingw32*) i[34567]86-*-mingw32* | x86_64-*-mingw*)
build_xm_file=i386/xm-mingw32.h build_xm_file=i386/xm-mingw32.h
build_exeext=.exe build_exeext=.exe
;; ;;

View File

@ -1343,7 +1343,7 @@ i[34567]86-*-pe | i[34567]86-*-cygwin*)
thread_file='posix' thread_file='posix'
fi 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" 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 xm_file=i386/xm-mingw32.h
tmake_file="i386/t-cygming i386/t-mingw32" tmake_file="i386/t-cygming i386/t-mingw32"

View File

@ -168,7 +168,7 @@ case ${host} in
host_xmake_file="${host_xmake_file} i386/x-cygwin" host_xmake_file="${host_xmake_file} i386/x-cygwin"
host_exeext=.exe host_exeext=.exe
;; ;;
i[34567]86-*-mingw32*) i[34567]86-*-mingw32* | x86_64-*-mingw*)
host_xm_file=i386/xm-mingw32.h host_xm_file=i386/xm-mingw32.h
host_xmake_file="${host_xmake_file} i386/x-mingw32" host_xmake_file="${host_xmake_file} i386/x-mingw32"
host_exeext=.exe host_exeext=.exe

View 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, the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */ 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 DBX_DEBUGGING_INFO 1
#define SDB_DEBUGGING_INFO 1 #define SDB_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE #undef PREFERRED_DEBUGGING_TYPE
#if TARGET_64BIT_DEFAULT
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
#else
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG #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 #ifdef HAVE_GAS_PE_SECREL32_RELOC
#define DWARF2_DEBUGGING_INFO 1 #define DWARF2_DEBUGGING_INFO 1
#undef DBX_REGISTER_NUMBER #undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(n) (write_symbols == DWARF2_DEBUG \ #define DBX_REGISTER_NUMBER(n) \
? svr4_dbx_register_map[n] \ (TARGET_64BIT ? dbx64_register_map[n] \
: dbx_register_map[n]) : (write_symbols == DWARF2_DEBUG \
? svr4_dbx_register_map[n] : dbx_register_map[n]))
/* Use section relative relocations for debugging offsets. Unlike /* Use section relative relocations for debugging offsets. Unlike
other targets that fake this by putting the section VMA at 0, PE 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 #undef MATH_LIBRARY
#define MATH_LIBRARY "" #define MATH_LIBRARY ""
#define SIZE_TYPE "unsigned int" #define SIZE_TYPE (TARGET_64BIT ? "long long unsigned int" : "unsigned int")
#define PTRDIFF_TYPE "int" #define PTRDIFF_TYPE (TARGET_64BIT ? "long long int" : "int")
#define WCHAR_TYPE_SIZE 16 #define WCHAR_TYPE_SIZE 16
#define WCHAR_TYPE "short unsigned int" #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). */ /* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
#define HANDLE_PRAGMA_PACK_PUSH_POP 1 #define HANDLE_PRAGMA_PACK_PUSH_POP 1
/* Enable push_macro & pop_macro */
#define HANDLE_PRAGMA_PUSH_POP_MACRO 1
union tree_node; union tree_node;
#define TREE union tree_node * #define TREE union tree_node *
@ -166,19 +201,21 @@ do { \
} while (0) } 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. */ bytes in one go. */
#define CHECK_STACK_LIMIT 4000 #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, /* By default, target has a 80387, uses IEEE compatible arithmetic,
returns float values in the 387 and needs stack probes. returns float values in the 387 and needs stack probes.
We also align doubles to 64-bits for MSVC default compatibility. */ We also align doubles to 64-bits for MSVC default compatibility. */
#undef TARGET_SUBTARGET_DEFAULT #undef TARGET_SUBTARGET_DEFAULT
#define TARGET_SUBTARGET_DEFAULT \ #define TARGET_SUBTARGET_DEFAULT \
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE \ (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS \
| MASK_ALIGN_DOUBLE) | MASK_STACK_PROBE | MASK_ALIGN_DOUBLE)
/* This is how to output an assembler line /* This is how to output an assembler line
that says to advance the location counter that says to advance the location counter
@ -245,7 +282,9 @@ do { \
/* DWARF2 Unwinding doesn't work with exception handling yet. To make /* 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 it work, we need to build a libgcc_s.dll, and dcrt0.o should be
changed to call __register_frame_info/__deregister_frame_info. */ changed to call __register_frame_info/__deregister_frame_info. */
#ifndef DWARF2_UNWIND_INFO
#define DWARF2_UNWIND_INFO 0 #define DWARF2_UNWIND_INFO 0
#endif
/* Don't assume anything about the header files. */ /* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C #define NO_IMPLICIT_EXTERN_C
@ -346,8 +385,8 @@ do { \
#define TARGET_USE_LOCAL_THUNK_ALIAS_P(DECL) (!DECL_ONE_ONLY (DECL)) #define TARGET_USE_LOCAL_THUNK_ALIAS_P(DECL) (!DECL_ONE_ONLY (DECL))
#define SUBTARGET_ATTRIBUTE_TABLE \ #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 } { "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. */ /* mcount() does not need a counter variable. */
#undef NO_PROFILE_COUNTERS #undef NO_PROFILE_COUNTERS

View File

@ -42,27 +42,66 @@
.global ___chkstk .global ___chkstk
.global __alloca .global __alloca
#ifndef _WIN64
___chkstk: ___chkstk:
__alloca: __alloca:
pushl %ecx /* save temp */ pushl %ecx /* save temp */
movl %esp,%ecx /* get sp */ leal 8(%esp), %ecx /* point past return addr */
addl $0x8,%ecx /* and point to return addr */ cmpl $0x1000, %eax /* > 4k ?*/
jb Ldone
probe: cmpl $0x1000,%eax /* > 4k ?*/ Lprobe:
jb done 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*/ Ldone:
orl $0x0,(%ecx) /* probe there */ subl %eax, %ecx
subl $0x1000,%eax /* decrement count */ orl $0x0, (%ecx) /* less than 4k, just peek here */
jmp probe /* and do it again */
done: subl %eax,%ecx movl %esp, %eax /* save old stack pointer */
orl $0x0,(%ecx) /* less that 4k, just peek here */ movl %ecx, %esp /* decrement stack */
movl (%eax), %ecx /* recover saved temp */
movl 4(%eax), %eax /* recover return address */
movl %esp,%eax /* Push the return value back. Doing this instead of just
movl %ecx,%esp /* decrement stack */ 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 */
movl (%eax),%ecx /* recover saved temp */ /* ___chkstk is a *special* function call, which uses %rax as the argument.
movl 4(%eax),%eax /* get return address */ We avoid clobbering the 4 integer argument registers, %rcx, %rdx,
jmp *%eax %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 #endif

View 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. */ C++ EH. Mingw uses a thread-support DLL to work-around this problem. */
int 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; int status = 0;
DWORD tls_index = TlsAlloc (); DWORD tls_index = TlsAlloc ();

View 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 */ 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] = 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. */ /* The "default" register map used in 64bit mode. */
@ -1857,9 +1863,16 @@ override_options (void)
} }
else else
{ {
ix86_cmodel = CM_32; /* For TARGET_64BIT_MS_ABI, force pic on, in order to enable the
if (TARGET_64BIT) 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; ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
else
ix86_cmodel = CM_32;
} }
if (ix86_asm_string != 0) if (ix86_asm_string != 0)
{ {
@ -1981,15 +1994,16 @@ override_options (void)
/* Validate -mregparm= value. */ /* Validate -mregparm= value. */
if (ix86_regparm_string) if (ix86_regparm_string)
{ {
if (TARGET_64BIT)
warning (0, "-mregparm is ignored in 64-bit mode");
i = atoi (ix86_regparm_string); i = atoi (ix86_regparm_string);
if (i < 0 || i > REGPARM_MAX) if (i < 0 || i > REGPARM_MAX)
error ("-mregparm=%d is not between 0 and %d", i, REGPARM_MAX); error ("-mregparm=%d is not between 0 and %d", i, REGPARM_MAX);
else else
ix86_regparm = i; ix86_regparm = i;
} }
else if (TARGET_64BIT)
if (TARGET_64BIT) ix86_regparm = REGPARM_MAX;
ix86_regparm = REGPARM_MAX;
/* If the user has provided any of the -malign-* options, /* If the user has provided any of the -malign-* options,
warn and use that value only if -falign-* is not set. warn and use that value only if -falign-* is not set.
@ -2135,18 +2149,16 @@ override_options (void)
if (TARGET_64BIT) if (TARGET_64BIT)
{ {
if (TARGET_ALIGN_DOUBLE)
error ("-malign-double makes no sense in the 64bit mode");
if (TARGET_RTD) 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 /* Enable by default the SSE and MMX builtins. Do allow the user to
explicitly disable any of these. In particular, disabling SSE and explicitly disable any of these. In particular, disabling SSE and
MMX for kernel code is extremely useful. */ MMX for kernel code is extremely useful. */
target_flags target_flags
|= ((MASK_SSE2 | MASK_SSE | MASK_MMX | MASK_128BIT_LONG_DOUBLE) |= ((MASK_SSE2 | MASK_SSE | MASK_MMX | TARGET_SUBTARGET64_DEFAULT)
& ~target_flags_explicit); & ~target_flags_explicit);
} }
else else
{ {
/* i386 ABI does not specify red zone. It still makes sense to use it /* 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) if (TARGET_64BIT)
{ {
warning (OPT_Wattributes, "%qs attribute ignored", /* Do not warn when emulating the MS ABI. */
IDENTIFIER_POINTER (name)); if (!TARGET_64BIT_MS_ABI)
warning (OPT_Wattributes, "%qs attribute ignored",
IDENTIFIER_POINTER (name));
*no_add_attrs = true; *no_add_attrs = true;
return NULL_TREE; return NULL_TREE;
} }
@ -2932,6 +2946,7 @@ bool
ix86_function_arg_regno_p (int regno) ix86_function_arg_regno_p (int regno)
{ {
int i; int i;
const int *parm_regs;
if (!TARGET_64BIT) if (!TARGET_64BIT)
{ {
@ -2959,11 +2974,15 @@ ix86_function_arg_regno_p (int regno)
} }
/* RAX is used as hidden argument to va_arg functions. */ /* RAX is used as hidden argument to va_arg functions. */
if (regno == 0) if (!TARGET_64BIT_MS_ABI && regno == 0)
return true; 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++) for (i = 0; i < REGPARM_MAX; i++)
if (regno == x86_64_int_parameter_registers[i]) if (regno == parm_regs[i])
return true; return true;
return false; return false;
} }
@ -3741,6 +3760,21 @@ function_arg_advance_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
cum->words += words; 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 void
function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
tree type, int named ATTRIBUTE_UNUSED) tree type, int named ATTRIBUTE_UNUSED)
@ -3756,7 +3790,9 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
if (type) if (type)
mode = type_natural_mode (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); function_arg_advance_64 (cum, mode, type, words);
else else
function_arg_advance_32 (cum, mode, type, bytes, words); 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); 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 rtx
function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode, function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode,
tree type, int named ATTRIBUTE_UNUSED) tree type, int named)
{ {
enum machine_mode mode = omode; enum machine_mode mode = omode;
HOST_WIDE_INT bytes, words; 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) if (type && TREE_CODE (type) == VECTOR_TYPE)
mode = type_natural_mode (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); return function_arg_64 (cum, mode, omode, type);
else else
return function_arg_32 (cum, mode, omode, type, bytes, words); 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, enum machine_mode mode ATTRIBUTE_UNUSED,
tree type, bool named 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 1;
return 0; return 0;
@ -4025,6 +4124,8 @@ ix86_function_value_regno_p (int regno)
return true; return true;
case FIRST_FLOAT_REG: case FIRST_FLOAT_REG:
if (TARGET_64BIT_MS_ABI)
return false;
return TARGET_FLOAT_RETURNS_IN_80387; return TARGET_FLOAT_RETURNS_IN_80387;
case FIRST_SSE_REG: case FIRST_SSE_REG:
@ -4131,6 +4232,22 @@ function_value_64 (enum machine_mode orig_mode, enum machine_mode mode,
return ret; return ret;
} }
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 static rtx
ix86_function_value_1 (tree valtype, tree fntype_or_decl, ix86_function_value_1 (tree valtype, tree fntype_or_decl,
enum machine_mode orig_mode, enum machine_mode mode) 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; fn = fntype_or_decl;
fntype = fn ? TREE_TYPE (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); return function_value_64 (orig_mode, mode, valtype);
else else
return function_value_32 (orig_mode, mode, fntype, fn); 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); 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 int
ix86_return_in_memory (tree type) ix86_return_in_memory (tree type)
{ {
enum machine_mode mode = type_natural_mode (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); return return_in_memory_64 (type, mode);
else else
return return_in_memory_32 (type, mode); 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; tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
/* For i386 we use plain pointer to argument area. */ /* 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); return build_pointer_type (char_type_node);
record = (*lang_hooks.types.make_type) (RECORD_TYPE); record = (*lang_hooks.types.make_type) (RECORD_TYPE);
@ -4399,6 +4533,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 static void
ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
tree type, int *pretend_size ATTRIBUTE_UNUSED, tree type, int *pretend_size ATTRIBUTE_UNUSED,
@ -4426,7 +4581,10 @@ ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
if (stdarg_p) if (stdarg_p)
function_arg_advance (&next_cum, mode, type, 1); 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. */ /* Implement va_start. */
@ -4440,7 +4598,7 @@ ix86_va_start (tree valist, rtx nextarg)
tree type; tree type;
/* Only 64bit target needs something special. */ /* Only 64bit target needs something special. */
if (!TARGET_64BIT) if (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
{ {
std_expand_builtin_va_start (valist, nextarg); std_expand_builtin_va_start (valist, nextarg);
return; return;
@ -4519,7 +4677,7 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
enum machine_mode nat_mode; enum machine_mode nat_mode;
/* Only 64bit target needs something special. */ /* 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); return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
@ -5711,21 +5869,30 @@ ix86_expand_prologue (void)
else else
{ {
/* Only valid for Win32. */ /* Only valid for Win32. */
rtx eax = gen_rtx_REG (SImode, 0); rtx eax = gen_rtx_REG (Pmode, 0);
bool eax_live = ix86_eax_live_at_start_p (); bool eax_live;
rtx t; 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) if (eax_live)
{ {
emit_insn (gen_push (eax)); emit_insn (gen_push (eax));
allocate -= 4; allocate -= UNITS_PER_WORD;
} }
emit_move_insn (eax, GEN_INT (allocate)); 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; RTX_FRAME_RELATED_P (insn) = 1;
t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-allocate)); t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-allocate));
t = gen_rtx_SET (VOIDmode, stack_pointer_rtx, t); t = gen_rtx_SET (VOIDmode, stack_pointer_rtx, t);
@ -5741,7 +5908,7 @@ ix86_expand_prologue (void)
- frame.nregs * UNITS_PER_WORD); - frame.nregs * UNITS_PER_WORD);
else else
t = plus_constant (stack_pointer_rtx, allocate); 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); 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); gcc_assert (!TARGET_64BIT);
emit_insn (gen_popsi1 (ecx)); emit_insn (gen_popsi1 (ecx));
@ -6848,7 +7015,8 @@ legitimize_pic_address (rtx orig, rtx reg)
addr = XEXP (addr, 0); addr = XEXP (addr, 0);
if (GET_CODE (addr) == PLUS) 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)); new = gen_rtx_PLUS (Pmode, new, XEXP (addr, 1));
} }
else else
@ -6879,7 +7047,8 @@ legitimize_pic_address (rtx orig, rtx reg)
addr = XEXP (addr, 0); addr = XEXP (addr, 0);
if (GET_CODE (addr) == PLUS) 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)); new = gen_rtx_PLUS (Pmode, new, XEXP (addr, 1));
} }
else else
@ -6898,6 +7067,11 @@ legitimize_pic_address (rtx orig, rtx reg)
see gotoff_operand. */ see gotoff_operand. */
|| (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF)) || (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) if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
{ {
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTPCREL); 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); 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)) if (SYMBOL_REF_DECL (x))
mark_decl_referenced (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 #endif
assemble_name (file, name); 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); fputs ("@PLT", file);
break; break;
@ -9291,7 +9467,6 @@ ix86_expand_clear (rtx dest)
/* Avoid HImode and its attendant prefix byte. */ /* Avoid HImode and its attendant prefix byte. */
if (GET_MODE_SIZE (GET_MODE (dest)) < 4) if (GET_MODE_SIZE (GET_MODE (dest)) < 4)
dest = gen_rtx_REG (SImode, REGNO (dest)); dest = gen_rtx_REG (SImode, REGNO (dest));
tmp = gen_rtx_SET (VOIDmode, dest, const0_rtx); tmp = gen_rtx_SET (VOIDmode, dest, const0_rtx);
/* This predicate should match that for movsi_xor and movdi_xor_rex64. */ /* This predicate should match that for movsi_xor and movdi_xor_rex64. */
@ -19508,37 +19683,29 @@ static rtx
x86_this_parameter (tree function) x86_this_parameter (tree function)
{ {
tree type = TREE_TYPE (function); tree type = TREE_TYPE (function);
bool aggr = aggregate_value_p (TREE_TYPE (type), type) != 0;
if (TARGET_64BIT) if (TARGET_64BIT)
{ {
int n = aggregate_value_p (TREE_TYPE (type), type) != 0; const int *parm_regs;
return gen_rtx_REG (DImode, x86_64_int_parameter_registers[n]);
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; int regno = 0;
if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
parm = TYPE_ARG_TYPES (type); regno = 2;
/* Figure out whether or not the function has a variable number of return gen_rtx_REG (SImode, regno);
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);
}
} }
if (aggregate_value_p (TREE_TYPE (type), type)) return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, aggr ? 8 : 4));
return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8));
else
return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4));
} }
/* Determine whether x86_output_mi_thunk can succeed. */ /* 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 */; int tmp_regno = 2 /* ECX */;
if (lookup_attribute ("fastcall", if (lookup_attribute ("fastcall",
TYPE_ATTRIBUTES (TREE_TYPE (function)))) TYPE_ATTRIBUTES (TREE_TYPE (function))))
tmp_regno = 0 /* EAX */; tmp_regno = 0 /* EAX */;
tmp = gen_rtx_REG (SImode, tmp_regno); 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)) if (!flag_pic || (*targetm.binds_local_p) (function))
output_asm_insn ("jmp\t%P0", xops); 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 else
{ {
tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xops[0]), UNSPEC_GOTPCREL); 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) x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
{ {
if (TARGET_64BIT) if (TARGET_64BIT)
if (flag_pic) {
{
#ifndef NO_PROFILE_COUNTERS #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 #endif
if (!TARGET_64BIT_MS_ABI && flag_pic)
fprintf (file, "\tcall\t*%s@GOTPCREL(%%rip)\n", MCOUNT_NAME); fprintf (file, "\tcall\t*%s@GOTPCREL(%%rip)\n", MCOUNT_NAME);
} else
else
{
#ifndef NO_PROFILE_COUNTERS
fprintf (file, "\tmovq\t$%sP%d,%%r11\n", LPREFIX, labelno);
#endif
fprintf (file, "\tcall\t%s\n", MCOUNT_NAME); fprintf (file, "\tcall\t%s\n", MCOUNT_NAME);
} }
else if (flag_pic) else if (flag_pic)
{ {
#ifndef NO_PROFILE_COUNTERS #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 #define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC #undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
#define TARGET_DWARF_HANDLE_FRAME_UNSPEC ix86_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 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
#define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg

View File

@ -20,40 +20,6 @@ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor, the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */ Boston, MA 02110-1301, USA. */
#include "config/vxworks-dummy.h"
/* Algorithm to expand string function with. */
enum stringop_alg
{
no_stringop,
libcall,
rep_prefix_1_byte,
rep_prefix_4_byte,
rep_prefix_8_byte,
loop_1_byte,
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
is walked in order until MAX is greater then the estimate (or -1
means infinity). Corresponding ALG is used then.
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.
*/
struct stringop_algs
{
const enum stringop_alg unknown_size;
const struct stringop_strategy {
const int max;
const enum stringop_alg alg;
} size [NAX_STRINGOP_ALGS];
};
/* The purpose of this file is to define the characteristics of the i386, /* The purpose of this file is to define the characteristics of the i386,
independent of assembler syntax or operating system. independent of assembler syntax or operating system.
@ -69,6 +35,41 @@ struct stringop_algs
ADDR_BEG, ADDR_END, PRINT_IREG, PRINT_SCALE, PRINT_B_I_S, and many ADDR_BEG, ADDR_END, PRINT_IREG, PRINT_SCALE, PRINT_B_I_S, and many
that start with ASM_ or end in ASM_OP. */ that start with ASM_ or end in ASM_OP. */
#include "config/vxworks-dummy.h"
/* Algorithm to expand string function with. */
enum stringop_alg
{
no_stringop,
libcall,
rep_prefix_1_byte,
rep_prefix_4_byte,
rep_prefix_8_byte,
loop_1_byte,
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
is walked in order until MAX is greater then the estimate (or -1
means infinity). Corresponding ALG is used then.
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. */
struct stringop_algs
{
const enum stringop_alg unknown_size;
const struct stringop_strategy {
const int max;
const enum stringop_alg alg;
} size [NAX_STRINGOP_ALGS];
};
/* Define the specific costs for a given cpu */ /* Define the specific costs for a given cpu */
struct processor_costs { struct processor_costs {
@ -372,11 +373,17 @@ extern int x86_prefetch_sse;
the frame pointer in leaf functions. */ the frame pointer in leaf functions. */
#define TARGET_DEFAULT 0 #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 /* 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 it's analogous to similar code for Mach-O on PowerPC. darwin.h
redefines this to 1. */ redefines this to 1. */
#define TARGET_MACHO 0 #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 /* Subtargets may reset this to 1 in order to enable 96-bit long double
with the rounding mode forced to 53 bits. */ with the rounding mode forced to 53 bits. */
#define TARGET_96_ROUND_53_LONG_DOUBLE 0 #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++) \ for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++) \
reg_names[i] = ""; \ reg_names[i] = ""; \
} \ } \
if (TARGET_64BIT_MS_ABI) \
{ \
call_used_regs[4 /*RSI*/] = 0; \
call_used_regs[5 /*RDI*/] = 0; \
} \
} while (0) } while (0)
/* Return number of consecutive hard regs needed starting at reg REGNO /* Return number of consecutive hard regs needed starting at reg REGNO

View File

@ -19611,86 +19611,56 @@
[(set_attr "type" "alu,lea") [(set_attr "type" "alu,lea")
(set_attr "mode" "DI")]) (set_attr "mode" "DI")])
(define_expand "allocate_stack_worker" (define_insn "allocate_stack_worker_32"
[(match_operand:SI 0 "register_operand" "")] [(set (match_operand:SI 0 "register_operand" "+a")
"TARGET_STACK_PROBE" (unspec_volatile:SI [(match_dup 0)] UNSPECV_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)
(set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0))) (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))] (clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && TARGET_STACK_PROBE" "!TARGET_64BIT && TARGET_STACK_PROBE"
"call\t__alloca" "call\t__alloca"
[(set_attr "type" "multi") [(set_attr "type" "multi")
(set_attr "length" "5")]) (set_attr "length" "5")])
(define_expand "allocate_stack_worker_postreload" (define_insn "allocate_stack_worker_64"
[(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")] [(set (match_operand:DI 0 "register_operand" "=a")
UNSPECV_STACK_PROBE) (unspec_volatile:DI [(match_dup 0)] 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)
(set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0))) (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))] (clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && TARGET_STACK_PROBE" "TARGET_64BIT && TARGET_STACK_PROBE"
"call\t__alloca" "call\t___chkstk"
[(set_attr "type" "multi") [(set_attr "type" "multi")
(set_attr "length" "5")]) (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" (define_expand "allocate_stack"
[(parallel [(set (match_operand:SI 0 "register_operand" "=r") [(match_operand 0 "register_operand" "")
(minus:SI (reg:SI SP_REG) (match_operand 1 "general_operand" "")]
(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))])]
"TARGET_STACK_PROBE" "TARGET_STACK_PROBE"
{ {
#ifdef CHECK_STACK_LIMIT rtx x;
if (CONST_INT_P (operands[1])
&& INTVAL (operands[1]) < CHECK_STACK_LIMIT) #ifndef CHECK_STACK_LIMIT
emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, #define CHECK_STACK_LIMIT 0
operands[1]));
else
#endif #endif
emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
operands[1]))); if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
&& INTVAL (operands[1]) < CHECK_STACK_LIMIT)
{
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
{
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); emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
DONE; DONE;

View File

@ -27,11 +27,6 @@ Boston, MA 02110-1301, USA. */
#define TARGET_VERSION fprintf (stderr, " (i386 bare ELF target)"); #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 /* The ELF ABI for the i386 says that records and unions are returned
in memory. */ in memory. */

View File

@ -21,7 +21,11 @@ the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */ Boston, MA 02110-1301, USA. */
#undef TARGET_VERSION #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. */ /* See i386/crtdll.h for an alternative definition. */
#define EXTRA_OS_CPP_BUILTINS() \ #define EXTRA_OS_CPP_BUILTINS() \
@ -32,13 +36,28 @@ Boston, MA 02110-1301, USA. */
builtin_define ("_WIN32"); \ builtin_define ("_WIN32"); \
builtin_define_std ("WIN32"); \ builtin_define_std ("WIN32"); \
builtin_define_std ("WINNT"); \ 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) while (0)
/* Override the standard choice of /usr/include as the default prefix /* Override the standard choice of /usr/include as the default prefix
to try when searching for header files. */ to try when searching for header files. */
#undef STANDARD_INCLUDE_DIR #undef STANDARD_INCLUDE_DIR
#if TARGET_64BIT_DEFAULT
#define STANDARD_INCLUDE_DIR "/mingw/include64"
#else
#define STANDARD_INCLUDE_DIR "/mingw/include" #define STANDARD_INCLUDE_DIR "/mingw/include"
#endif
#undef STANDARD_INCLUDE_COMPONENT #undef STANDARD_INCLUDE_COMPONENT
#define STANDARD_INCLUDE_COMPONENT "MINGW" #define STANDARD_INCLUDE_COMPONENT "MINGW"
@ -71,8 +90,12 @@ Boston, MA 02110-1301, USA. */
/* Override startfile prefix defaults. */ /* Override startfile prefix defaults. */
#ifndef STANDARD_STARTFILE_PREFIX_1 #ifndef STANDARD_STARTFILE_PREFIX_1
#if TARGET_64BIT_DEFAULT
#define STANDARD_STARTFILE_PREFIX_1 "/mingw/lib64/"
#else
#define STANDARD_STARTFILE_PREFIX_1 "/mingw/lib/" #define STANDARD_STARTFILE_PREFIX_1 "/mingw/lib/"
#endif #endif
#endif
#ifndef STANDARD_STARTFILE_PREFIX_2 #ifndef STANDARD_STARTFILE_PREFIX_2
#define STANDARD_STARTFILE_PREFIX_2 "" #define STANDARD_STARTFILE_PREFIX_2 ""
#endif #endif

View File

@ -61,5 +61,10 @@ Boston, MA 02110-1301, USA. */
/* By default, target has a 80387, uses IEEE compatible arithmetic, /* By default, target has a 80387, uses IEEE compatible arithmetic,
and returns float values in the 387. */ 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

View File

@ -562,7 +562,8 @@ __gthread_once (__gthread_once_t *once, void (*func) (void))
leaks, especially in threaded applications making extensive use of leaks, especially in threaded applications making extensive use of
C++ EH. Mingw uses a thread-support DLL to work-around this problem. */ C++ EH. Mingw uses a thread-support DLL to work-around this problem. */
static inline int 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; int status = 0;
DWORD tls_index = TlsAlloc (); DWORD tls_index = TlsAlloc ();

View 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> 2007-03-23 Michael Meissner <michael.meissner@amd.com>
H.J. Lu <hongjiu.lu@intel.com> H.J. Lu <hongjiu.lu@intel.com>

View 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-*-pe | i[34567]86-*-cygwin*)
;; ;;
i[34567]86-*-mingw32*) i[34567]86-*-mingw32* | x86_64-*-mingw*)
;; ;;
i[34567]86-*-uwin*) i[34567]86-*-uwin*)
;; ;;