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:
parent
8318b0d99a
commit
ccf8e764e9
16 changed files with 542 additions and 207 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
;;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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*)
|
||||
;;
|
||||
|
|
Loading…
Add table
Reference in a new issue