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>
Kai Tietz <kai.tietz@onevision.com>

View File

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

View File

@ -1343,7 +1343,7 @@ i[34567]86-*-pe | i[34567]86-*-cygwin*)
thread_file='posix'
fi
;;
i[34567]86-*-mingw32*)
i[34567]86-*-mingw32* | x86_64-*-mingw32*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/mingw32.h"
xm_file=i386/xm-mingw32.h
tmake_file="i386/t-cygming i386/t-mingw32"

View File

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

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,
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

View File

@ -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 */
movl (%eax),%ecx /* recover saved temp */
movl 4(%eax),%eax /* get return address */
jmp *%eax
/* ___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

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. */
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 ();

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 */
};
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:
@ -4131,6 +4232,22 @@ function_value_64 (enum machine_mode orig_mode, enum machine_mode mode,
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
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);
@ -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
ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
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)
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

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,
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,
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
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 */
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

View File

@ -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])
&& INTVAL (operands[1]) < CHECK_STACK_LIMIT)
emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
operands[1]));
else
rtx x;
#ifndef CHECK_STACK_LIMIT
#define CHECK_STACK_LIMIT 0
#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);
DONE;

View File

@ -27,11 +27,6 @@ Boston, MA 02110-1301, USA. */
#define TARGET_VERSION fprintf (stderr, " (i386 bare ELF target)");
/* By default, target has a 80387, uses IEEE compatible arithmetic,
and returns float values in the 387. */
#define TARGET_SUBTARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
/* The ELF ABI for the i386 says that records and unions are returned
in memory. */

View File

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

View File

@ -61,5 +61,10 @@ Boston, MA 02110-1301, USA. */
/* By default, target has a 80387, uses IEEE compatible arithmetic,
and returns float values in the 387. */
#define TARGET_SUBTARGET_DEFAULT \
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
#define TARGET_SUBTARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
/* By default, 64-bit mode uses 128-bit long double. */
#undef TARGET_SUBTARGET64_DEFAULT
#define TARGET_SUBTARGET64_DEFAULT \
MASK_128BIT_LONG_DOUBLE

View File

@ -562,7 +562,8 @@ __gthread_once (__gthread_once_t *once, void (*func) (void))
leaks, especially in threaded applications making extensive use of
C++ EH. Mingw uses a thread-support DLL to work-around this problem. */
static inline int
__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
__gthread_key_create (__gthread_key_t *key,
void (*dtor) (void *) __attribute__((unused)))
{
int status = 0;
DWORD tls_index = TlsAlloc ();

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