PATCH: Updated version of x86_64-pc-mingw32 support of gcc.
Kai Tietz
Kai.Tietz@onevision.com
Fri Mar 16 14:16:00 GMT 2007
Paolo Bonzini <paolo.bonzini@lu.unisi.ch> wrote on 16.03.2007 13:48:59:
> Can you please put patches inline? I will then review the build parts.
Ok, here we are:
ChangeLog:
2007-03-15 Kai Tietz <kai.tietz@onevision.com>
* gcc/config/i386/cygming.h: (DWARF2_DEBUGGING_INFO) for
x86_64-mingw needs to be valued 1
(DWARF2_UNWIND_INFO): Likewise
(PREFERRED_DEBUGGING_TYPE): for x86_64-mingw it needs to be
DWARF2_DEBUG by default
(DBX_REGISTER_NUMBER): Have to use dbx64_register_map for
x86_64-mingw
(SIZE_TYPE): Needs to be "long long unsigned int" for
x86_64-mingw
(PTRDIFF_TYPE): Needs to be "long long int" for x86_64-mingw
(POINTER_SIZE: Needs to be 64 for x86_64 mingw
(HANDLE_PRAGMA_PUSH_POP_MACRO): New macro
(TARGET_SUBTARGET_DEFAULT): Defined proper for x86_64-mingw
* gcc/config/i386/cygwin.asm: Adjustments for target build of
x86_64-mingw (and cygwin)
* gcc/config/i386/i386.c: New calling convention and target
support
* gcc/config/i386/i386.h: Add new target
(call_used_regs): Adjustments for target
(REGPARM_MAX): Likewise
(SSE_REGPARM_MAX): Likewise
(LONG_TYPE_SIZE): Likewise
(REG_PARM_STACK_SPACE): Likewise
(OUTGOING_REG_PARM_STACK_SPACE): Added
* gcc/config/i386/i386.md (allocate_stack64): New
* gcc/config/i386/i386.opt (64BIT_MS_ABI): New
* gcc/config/i386/mingw32.h: Adjustments for target x86_64-mingw
(EXTRA_OS_CPP_BUILTINS): Added predefined macro
_INTEGRAL_MAX_BITS with the value of bitsize of a pointer
(WIN64,_WIN64,__MINGW64__): New predefined macros for
x86_64-mingw target
(STANDARD_INCLUDE_DIR,STANDARD_STARTFILE_PREFIX_1,): Include for
x86_64-mingw from different place
* gcc/config.build: Add x86_64-*-mingw32* target
* gcc/config.gcc: Add x86_64-*-mingw32* target
* gcc/config.host: Add x86_64-*-mingw32* target
* gcc/expr.c (OUTGOING_REG_PARM_STACK_SPACE): Changed definition
and clauses
* gcc/function.c (OUTGOING_REG_PARM_STACK_SPACE): Ditto
* gcc/calls.c (OUTGOING_REG_PARM_STACK_SPACE): Ditto
* gcc/config/iq2000/iq2000.h (OUTGOING_REG_PARM_STACK_SPACE):
Ditto
* gcc/config/mips/mips.h (OUTGOING_REG_PARM_STACK_SPACE): Ditto
* gcc/config/mn10300/mn10300.h (OUTGOING_REG_PARM_STACK_SPACE):
Ditto
* gcc/config/mt/mt.h (OUTGOING_REG_PARM_STACK_SPACE): Ditto
* gcc/config/pa/pa.h (OUTGOING_REG_PARM_STACK_SPACE): Ditto
* gcc/config/rs6000/rs6000.h (OUTGOING_REG_PARM_STACK_SPACE):
Ditto
* gcc/config/score/score.h (OUTGOING_REG_PARM_STACK_SPACE): Ditto
* gcc/config/spu/spu.h (OUTGOING_REG_PARM_STACK_SPACE): Ditto
* gcc/config/v850/v850.h (OUTGOING_REG_PARM_STACK_SPACE): Ditto
* gcc/unwind-generic.h (_uleb128_t): Adjust type for win64 target
(_sleb128_t): Ditto
* gcc/doc/tm.texi (OUTGOING_REG_PARM_STACK_SPACE): Adjust
documentation
(HANDLE_PRAGMA_PUSH_POP_MACRO): Add new
* fixincludes/mkfixinc.sh: Add x86_64-mingw target
* libgcc/config.host: Add support for an x86_64-mingw* target.
Patch: (I add it also as file for savety, but may the changes to my mailer
work.)
diff -ubNr -X ../../excl.txt gcc/calls.c ../../gcc/gcc/calls.c
--- gcc/calls.c 2007-03-13 17:16:19.056732000 +0100
+++ ../../gcc/gcc/calls.c 2007-02-28 15:22:22.651143200 +0100
@@ -42,6 +42,11 @@
#include "cgraph.h"
#include "except.h"
+#ifndef OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 0
+#endif
+
+
/* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */
#define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
@@ -1222,13 +1227,12 @@
= size_binop (MAX_EXPR, args_size->var,
ssize_int (reg_parm_stack_space));
-#ifndef OUTGOING_REG_PARM_STACK_SPACE
/* The area corresponding to register parameters is not to count
in
the size of the block we need. So make the adjustment. */
+ if (!OUTGOING_REG_PARM_STACK_SPACE)
args_size->var
= size_binop (MINUS_EXPR, args_size->var,
ssize_int (reg_parm_stack_space));
-#endif
}
}
else
@@ -1246,9 +1250,8 @@
args_size->constant = MAX (args_size->constant,
reg_parm_stack_space);
-#ifndef OUTGOING_REG_PARM_STACK_SPACE
+ if (!OUTGOING_REG_PARM_STACK_SPACE)
args_size->constant -= reg_parm_stack_space;
-#endif
}
return unadjusted_args_size;
}
@@ -2026,10 +2029,8 @@
reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
#endif
-#ifndef OUTGOING_REG_PARM_STACK_SPACE
- if (reg_parm_stack_space > 0 && PUSH_ARGS)
+ if (!OUTGOING_REG_PARM_STACK_SPACE && reg_parm_stack_space > 0 &&
PUSH_ARGS)
must_preallocate = 1;
-#endif
/* Set up a place to return a structure. */
@@ -2430,12 +2431,11 @@
Another approach might be to try to reorder the
argument
evaluations to avoid this conflicting stack usage. */
-#ifndef OUTGOING_REG_PARM_STACK_SPACE
/* Since we will be writing into the entire argument
area,
the map must be allocated for its entire size, not
just
the part that is the responsibility of the caller. */
+ if (!OUTGOING_REG_PARM_STACK_SPACE)
needed += reg_parm_stack_space;
-#endif
#ifdef ARGS_GROW_DOWNWARD
highest_outgoing_arg_in_use = MAX
(initial_highest_arg_in_use,
@@ -2531,12 +2531,8 @@
an argument. */
if (stack_arg_under_construction)
{
-#ifndef OUTGOING_REG_PARM_STACK_SPACE
- rtx push_size = GEN_INT (reg_parm_stack_space
- + adjusted_args_size.constant);
-#else
- rtx push_size = GEN_INT (adjusted_args_size.constant);
-#endif
+ rtx push_size = (!OUTGOING_REG_PARM_STACK_SPACE ? (GEN_INT
(reg_parm_stack_space
+ + adjusted_args_size.constant)) :
(GEN_INT (adjusted_args_size.constant)));
if (old_stack_level == 0)
{
emit_stack_save (SAVE_BLOCK, &old_stack_level,
@@ -2706,11 +2702,9 @@
/* If register arguments require space on the stack and stack space
was not preallocated, allocate stack space here for arguments
passed in registers. */
-#ifdef OUTGOING_REG_PARM_STACK_SPACE
- if (!ACCUMULATE_OUTGOING_ARGS
+ if (OUTGOING_REG_PARM_STACK_SPACE && !ACCUMULATE_OUTGOING_ARGS
&& must_preallocate == 0 && reg_parm_stack_space > 0)
anti_adjust_stack (GEN_INT (reg_parm_stack_space));
-#endif
/* Pass the function the address in which to return a
structure value. */
@@ -3532,9 +3526,8 @@
args_size.constant = MAX (args_size.constant,
reg_parm_stack_space);
-#ifndef OUTGOING_REG_PARM_STACK_SPACE
+ if (!OUTGOING_REG_PARM_STACK_SPACE)
args_size.constant -= reg_parm_stack_space;
-#endif
if (args_size.constant > current_function_outgoing_args_size)
current_function_outgoing_args_size = args_size.constant;
@@ -3555,12 +3548,11 @@
needed = args_size.constant;
-#ifndef OUTGOING_REG_PARM_STACK_SPACE
/* Since we will be writing into the entire argument area, the
map must be allocated for its entire size, not just the part that
is the responsibility of the caller. */
+ if (!OUTGOING_REG_PARM_STACK_SPACE)
needed += reg_parm_stack_space;
-#endif
#ifdef ARGS_GROW_DOWNWARD
highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
diff -ubNr -X ../../excl.txt gcc/config/i386/cygming.h
../../gcc/gcc/config/i386/cygming.h
--- gcc/config/i386/cygming.h 2007-03-13 17:17:26.749411600 +0100
+++ ../../gcc/gcc/config/i386/cygming.h 2007-01-29 10:52:55.861644600
+0100
@@ -21,18 +21,31 @@
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
#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])
+ ? (TARGET_64BIT ? dbx64_register_map[n] :
svr4_dbx_register_map[n]) \
+ : (TARGET_64BIT ? dbx64_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 +110,17 @@
#undef MATH_LIBRARY
#define MATH_LIBRARY ""
-#define SIZE_TYPE "unsigned int"
-#define PTRDIFF_TYPE "int"
+#define SIZE_TYPE (TARGET_64BIT ? (TARGET_64BIT_MS_ABI ? "long long
unsigned int" : "long unsigned int") : "unsigned int")
+#define PTRDIFF_TYPE (TARGET_64BIT ? (TARGET_64BIT_MS_ABI ? "long long
int" : "long int") : "int")
#define WCHAR_TYPE_SIZE 16
#define WCHAR_TYPE "short unsigned int"
+#define POINTER_SIZE (TARGET_64BIT ? 64 : 32)
/* 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 *
@@ -194,10 +210,15 @@
returns float values in the 387 and needs stack probes.
We also align doubles to 64-bits for MSVC default compatibility. */
+#if TARGET_64BIT_DEFAULT
+#undef TARGET_SUBTARGET_DEFAULT
+#define TARGET_SUBTARGET_DEFAULT \
+ (MASK_64BIT | MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS |
MASK_64BIT | MASK_64BIT_MS_ABI)
+#else
#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)
+#endif
/* This is how to output an assembler line
that says to advance the location counter
@@ -266,7 +287,9 @@
/* 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
@@ -375,8 +398,8 @@
#define TARGET_USE_LOCAL_THUNK_ALIAS_P(DECL) (!DECL_ONE_ONLY (DECL))
#define SUBTARGET_ATTRIBUTE_TABLE \
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler }
*/ \
{ "selectany", 0, 0, true, false, false,
ix86_handle_selectany_attribute }
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler }
*/
/* mcount() does not need a counter variable. */
#undef NO_PROFILE_COUNTERS
diff -ubNr -X ../../excl.txt gcc/config/i386/cygwin.asm
../../gcc/gcc/config/i386/cygwin.asm
--- gcc/config/i386/cygwin.asm 2007-03-12 15:33:15.313756900 +0100
+++ ../../gcc/gcc/config/i386/cygwin.asm 2007-03-14
12:54:49.848147900 +0100
@@ -44,6 +44,7 @@
.global __alloca
___chkstk:
__alloca:
+#ifndef _WIN64
pushl %ecx /* save temp */
movl %esp,%ecx /* get sp */
addl $0x8,%ecx /* and point to return addr */
@@ -65,4 +66,27 @@
movl (%eax),%ecx /* recover saved temp */
movl 4(%eax),%eax /* get return address */
jmp *%eax
+#else
+ pushq %rdx /* save temp */
+ movq %rsp,%rdx /* get sp */
+ addq $0x10,%rdx /* and point to return addr */
+
+probe: cmpq $0x1000,%rcx /* > 4k ?*/
+ jb done
+
+ subq $0x1000,%rdx /* yes, move pointer down 4k*/
+ orq $0x0,(%rdx) /* probe there */
+ subq $0x1000,%rcx /* decrement count */
+ jmp probe /* and do it again */
+
+done: subq %rcx,%rdx
+ orq $0x0,(%rdx) /* less that 4k, just peek here */
+
+ movq %rsp,%rax
+ movq %rdx,%rsp /* decrement stack */
+
+ movq (%rax),%rdx /* recover saved temp */
+ movq 8(%rax),%rax /* get return address */
+ jmp *%rax
+#endif
#endif
diff -ubNr -X ../../excl.txt gcc/config/i386/i386.c
../../gcc/gcc/config/i386/i386.c
--- gcc/config/i386/i386.c 2007-03-14 09:11:03.690147900 +0100
+++ ../../gcc/gcc/config/i386/i386.c 2007-03-14 12:20:47.773063500
+0100
@@ -1277,9 +1277,15 @@
FIRST_REX_INT_REG /*R8 */, FIRST_REX_INT_REG + 1 /*R9 */
};
+static int const x86_64_ms_abi_int_parameter_registers[6] =
+{
+ 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. */
@@ -2086,7 +2092,7 @@
{
ix86_cmodel = CM_32;
if (TARGET_64BIT)
- ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
+ ix86_cmodel = (TARGET_64BIT_MS_ABI ? (flag_pic ? CM_MEDIUM_PIC :
CM_MEDIUM) : (flag_pic ? CM_SMALL_PIC : CM_SMALL));
}
if (ix86_asm_string != 0)
{
@@ -2867,7 +2873,7 @@
return NULL_TREE;
}
- if (TARGET_64BIT)
+ if (TARGET_64BIT && !TARGET_64BIT_MS_ABI)
{
warning (OPT_Wattributes, "%qs attribute ignored",
IDENTIFIER_POINTER (name));
@@ -2984,7 +2990,7 @@
}
/* Use register calling convention for local functions when
possible. */
- if (!TARGET_64BIT && !user_convention && decl
+ if ((!TARGET_64BIT || TARGET_64BIT_MS_ABI) && !user_convention &&
decl
&& flag_unit_at_a_time && !profile_flag)
{
struct cgraph_local_info *i = cgraph_local_info (decl);
@@ -3113,8 +3119,8 @@
int rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) !=
IDENTIFIER_NODE);
/* Cdecl functions override -mrtd, and never pop the stack. */
- if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {
-
+ if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype)))
+ {
/* Stdcall and fastcall functions will pop the stack if not
variable args. */
if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype))
@@ -3130,7 +3136,7 @@
/* Lose any fake structure return argument if it is passed on the
stack. */
if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
- && !TARGET_64BIT
+ && (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
&& !KEEP_AGGREGATE_RETURN_POINTER)
{
int nregs = ix86_function_regparm (funtype, fundecl);
@@ -3149,6 +3155,7 @@
ix86_function_arg_regno_p (int regno)
{
int i;
+ const int *x86_64_int_parameter_registers_ptr;
if (!TARGET_64BIT)
{
if (TARGET_MACHO)
@@ -3174,10 +3181,15 @@
return true;
}
/* RAX is used as hidden argument to va_arg functions. */
- if (!regno)
+ if (!TARGET_64BIT_MS_ABI && !regno)
return true;
+ if (TARGET_64BIT_MS_ABI)
+ x86_64_int_parameter_registers_ptr =
x86_64_ms_abi_int_parameter_registers;
+ else
+ x86_64_int_parameter_registers_ptr = x86_64_int_parameter_registers;
+
for (i = 0; i < REGPARM_MAX; i++)
- if (regno == x86_64_int_parameter_registers[i])
+ if (regno == x86_64_int_parameter_registers_ptr[i])
return true;
return false;
}
@@ -3276,6 +3288,13 @@
cum->fastcall = 0;
cum->float_in_sse = 0;
}
+ else if(TARGET_64BIT_MS_ABI)
+ {
+ cum->mmx_nregs = 0;
+ cum->warn_mmx = 0;
+ cum->fastcall = 0;
+ cum->float_in_sse = 1;
+ }
cum->maybe_vaarg = true;
}
}
@@ -3339,9 +3358,42 @@
static rtx
gen_reg_or_parallel (enum machine_mode mode, enum machine_mode orig_mode,
- unsigned int regno)
+ unsigned int regno,const int **intreg)
{
- rtx tmp;
+ rtx tmp,tmp2;
+ if (TARGET_64BIT_MS_ABI && intreg)
+ {
+ enum machine_mode shadow_mode= SImode;
+ int shadow=-1;
+
+ if (regno >= FIRST_SSE_REG && regno<=LAST_SSE_REG)
+ {
+ shadow=regno-FIRST_SSE_REG; shadow_mode=DImode;
+ }
+ else if (regno >= FIRST_MMX_REG && regno <= LAST_MMX_REG)
+ shadow=regno-FIRST_MMX_REG;
+ if (shadow!=-1)
+ {
+ shadow=**intreg; intreg[0]++;
+ if (orig_mode != BLKmode)
+ {
+ tmp = gen_rtx_REG (orig_mode, regno);
+ tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
+ tmp2= gen_rtx_REG (shadow_mode, (unsigned int) shadow);
+ tmp2 = gen_rtx_EXPR_LIST (VOIDmode, tmp2, const0_rtx);
+ tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (2, tmp,
tmp2));
+ }
+ else
+ {
+ tmp = gen_rtx_REG (mode, regno);
+ tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
+ tmp2= gen_rtx_REG (shadow_mode, (unsigned int) shadow);
+ tmp2 = gen_rtx_EXPR_LIST (VOIDmode, tmp2, const0_rtx);
+ tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (2, tmp,
tmp2));
+ }
+ return tmp;
+ }
+ }
if (orig_mode != BLKmode)
tmp = gen_rtx_REG (orig_mode, regno);
@@ -3703,11 +3755,15 @@
case X86_64_INTEGER_CLASS:
case X86_64_INTEGERSI_CLASS:
(*int_nregs)++;
+ if (TARGET_64BIT_MS_ABI)
+ (*sse_nregs)++;
break;
case X86_64_SSE_CLASS:
case X86_64_SSESF_CLASS:
case X86_64_SSEDF_CLASS:
(*sse_nregs)++;
+ if (TARGET_64BIT_MS_ABI)
+ (*int_nregs)++;
break;
case X86_64_NO_CLASS:
case X86_64_SSEUP_CLASS:
@@ -3746,7 +3802,7 @@
int i;
int nexps = 0;
int needed_sseregs, needed_intregs;
- rtx exp[MAX_CLASSES];
+ rtx exp[MAX_CLASSES*2];
rtx ret;
n = classify_argument (mode, type, class, 0);
@@ -3819,7 +3875,7 @@
case X86_64_SSE_CLASS:
case X86_64_SSESF_CLASS:
case X86_64_SSEDF_CLASS:
- return gen_reg_or_parallel (mode, orig_mode, SSE_REGNO
(sse_regno));
+ return gen_reg_or_parallel (mode, orig_mode, SSE_REGNO
(sse_regno),&intreg);
case X86_64_X87_CLASS:
case X86_64_COMPLEX_X87_CLASS:
return gen_rtx_REG (mode, FIRST_STACK_REG);
@@ -3831,7 +3887,20 @@
}
if (n == 2 && class[0] == X86_64_SSE_CLASS && class[1] ==
X86_64_SSEUP_CLASS
&& mode != BLKmode)
+ {
+ if (TARGET_64BIT_MS_ABI)
+ {
+ rtx tmp,tmp2;
+ tmp = gen_rtx_REG (mode, SSE_REGNO (sse_regno));
+ tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
+ tmp2= gen_rtx_REG (DImode, intreg[0]);
+ tmp2 = gen_rtx_EXPR_LIST (VOIDmode, tmp2, const0_rtx);
+ tmp = gen_rtx_PARALLEL (mode, gen_rtvec (2, tmp, tmp2));
+ return tmp;
+ }
return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
+ }
+
if (n == 2
&& class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS)
return gen_rtx_REG (XFmode, FIRST_STACK_REG);
@@ -3864,6 +3933,7 @@
gen_rtx_REG (tmpmode,
*intreg),
GEN_INT (i*8));
intreg++;
+ if (TARGET_64BIT_MS_ABI) sse_regno++;
break;
case X86_64_SSESF_CLASS:
exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
@@ -3871,6 +3941,13 @@
SSE_REGNO
(sse_regno)),
GEN_INT (i*8));
sse_regno++;
+ if (TARGET_64BIT_MS_ABI)
+ {
+ exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (DImode,
*intreg),
+ GEN_INT (i*8));
+ intreg++;
+ }
break;
case X86_64_SSEDF_CLASS:
exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
@@ -3878,6 +3955,11 @@
SSE_REGNO
(sse_regno)),
GEN_INT (i*8));
sse_regno++;
+ if (TARGET_64BIT_MS_ABI)
+ {
+ exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG
(DImode, *intreg),GEN_INT (i*8));
+ intreg++;
+ }
break;
case X86_64_SSE_CLASS:
if (i < n - 1 && class[i + 1] == X86_64_SSEUP_CLASS)
@@ -3891,6 +3973,11 @@
if (tmpmode == TImode)
i++;
sse_regno++;
+ if (TARGET_64BIT_MS_ABI)
+ {
+ exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,gen_rtx_REG
(tmpmode, *intreg),GEN_INT (i*8));
+ intreg++;
+ }
break;
default:
gcc_unreachable ();
@@ -4040,6 +4127,7 @@
int bytes =
(mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE
(mode);
int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ const int *x86_64_int_parameter_registers_ptr;
static bool warnedsse, warnedmmx;
/* To simplify the code below, represent vector types with a vector
mode
@@ -4052,7 +4140,7 @@
any AL settings. */
if (mode == VOIDmode)
{
- if (TARGET_64BIT)
+ if (TARGET_64BIT && !TARGET_64BIT_MS_ABI)
return GEN_INT (cum->maybe_vaarg
? (cum->sse_nregs < 0
? SSE_REGPARM_MAX
@@ -4062,10 +4150,16 @@
return constm1_rtx;
}
if (TARGET_64BIT)
+ {
+ if (TARGET_64BIT_MS_ABI)
+ x86_64_int_parameter_registers_ptr =
x86_64_ms_abi_int_parameter_registers;
+ else
+ x86_64_int_parameter_registers_ptr =
x86_64_int_parameter_registers;
ret = construct_container (mode, orig_mode, type, 0, cum->nregs,
cum->sse_nregs,
- &x86_64_int_parameter_registers
[cum->regno],
+ &x86_64_int_parameter_registers_ptr
[cum->regno],
cum->sse_regno);
+ }
else
switch (mode)
{
@@ -4089,7 +4183,7 @@
smaller arguments to ECX and EDX. */
if (cum->fastcall)
{
- if (mode == BLKmode || mode == DImode)
+ if (mode == BLKmode || (mode == DImode && !TARGET_64BIT))
break;
/* ECX not EAX is the first allocated register. */
@@ -4123,7 +4217,7 @@
}
if (cum->sse_nregs)
ret = gen_reg_or_parallel (mode, orig_mode,
- cum->sse_regno + FIRST_SSE_REG);
+ cum->sse_regno +
FIRST_SSE_REG,NULL);
}
break;
case V8QImode:
@@ -4140,7 +4234,7 @@
}
if (cum->mmx_nregs)
ret = gen_reg_or_parallel (mode, orig_mode,
- cum->mmx_regno + FIRST_MMX_REG);
+ cum->mmx_regno +
FIRST_MMX_REG,NULL);
}
break;
}
@@ -4507,7 +4601,7 @@
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);
@@ -4560,9 +4654,29 @@
tree fntype;
int stdarg_p;
int i;
+ const int *x86_64_int_parameter_registers_ptr;
- if (!TARGET_64BIT)
+ if (!TARGET_64BIT || TARGET_64BIT_MS_ABI)
+ {
+ if (TARGET_64BIT_MS_ABI)
+ {
+ if (!no_rtl)
+ save_area = frame_pointer_rtx;
+
+ set = get_varargs_alias_set ();
+ x86_64_int_parameter_registers_ptr =
x86_64_ms_abi_int_parameter_registers;
+ for (i = 0; i < ix86_regparm; i++)
+ {
+ 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);
+ emit_move_insn (mem, gen_rtx_REG (Pmode,
+ x86_64_int_parameter_registers_ptr[i]));
+ }
+ }
return;
+ }
if (! cfun->va_list_gpr_size && ! cfun->va_list_fpr_size)
return;
@@ -4588,6 +4702,11 @@
set = get_varargs_alias_set ();
+ if (TARGET_64BIT_MS_ABI)
+ x86_64_int_parameter_registers_ptr =
x86_64_ms_abi_int_parameter_registers;
+ else
+ x86_64_int_parameter_registers_ptr = x86_64_int_parameter_registers;
+
for (i = next_cum.regno;
i < ix86_regparm
&& i < next_cum.regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
@@ -4598,7 +4717,7 @@
MEM_NOTRAP_P (mem) = 1;
set_mem_alias_set (mem, set);
emit_move_insn (mem, gen_rtx_REG (Pmode,
- x86_64_int_parameter_registers[i]));
+ x86_64_int_parameter_registers_ptr[i]));
}
if (next_cum.sse_nregs && cfun->va_list_fpr_size)
@@ -4660,7 +4779,7 @@
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;
@@ -4743,7 +4862,7 @@
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));
@@ -5350,9 +5469,18 @@
ASM_OUTPUT_LABEL (asm_out_file, name);
}
+ if(!TARGET_64BIT)
+ {
xops[0] = gen_rtx_REG (SImode, regno);
xops[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
output_asm_insn ("mov{l}\t{%1, %0|%0, %1}", xops);
+ }
+ else
+ {
+ xops[0] = gen_rtx_REG (DImode, regno);
+ xops[1] = gen_rtx_MEM (DImode, stack_pointer_rtx);
+ output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", xops);
+ }
output_asm_insn ("ret", xops);
}
@@ -5935,11 +6063,11 @@
else
{
/* Only valid for Win32. */
- rtx eax = gen_rtx_REG (SImode, 0);
+ rtx eax = gen_rtx_REG ((TARGET_64BIT ? DImode : SImode), 0);
bool eax_live = ix86_eax_live_at_start_p ();
rtx t;
- gcc_assert (!TARGET_64BIT);
+ gcc_assert (!TARGET_64BIT || TARGET_64BIT_MS_ABI);
if (eax_live)
{
@@ -5965,7 +6093,7 @@
- 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 ((!TARGET_64BIT ? SImode :
DImode), t));
}
}
@@ -6220,13 +6348,22 @@
rtx ecx = gen_rtx_REG (SImode, 2);
/* There is no "pascal" calling convention in 64bit ABI. */
- gcc_assert (!TARGET_64BIT);
+ gcc_assert (!TARGET_64BIT || TARGET_64BIT_MS_ABI);
+ if(!TARGET_64BIT)
+ {
emit_insn (gen_popsi1 (ecx));
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
popc));
emit_jump_insn (gen_return_indirect_internal (ecx));
}
else
+ {
+ emit_insn (gen_popdi1 (ecx));
+ emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
popc));
+ emit_jump_insn (gen_return_indirect_internal (ecx));
+ }
+ }
+ else
emit_jump_insn (gen_return_pop_internal (popc));
}
else
@@ -9431,9 +9568,16 @@
gcc_assert (reload_completed);
/* Avoid HImode and its attendant prefix byte. */
+ if(!TARGET_64BIT)
+ {
if (GET_MODE_SIZE (GET_MODE (dest)) < 4)
dest = gen_rtx_REG (SImode, REGNO (dest));
-
+ }
+ else
+ {
+ if (GET_MODE_SIZE (GET_MODE (dest)) < 8)
+ dest = gen_rtx_REG (DImode, REGNO (dest));
+ }
tmp = gen_rtx_SET (VOIDmode, dest, const0_rtx);
/* This predicate should match that for movsi_xor and movdi_xor_rex64.
*/
@@ -19550,7 +19694,13 @@
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 *x86_64_int_parameter_registers_ptr;
+
+ if (TARGET_64BIT_MS_ABI)
+ x86_64_int_parameter_registers_ptr =
x86_64_ms_abi_int_parameter_registers;
+ else
+ x86_64_int_parameter_registers_ptr =
x86_64_int_parameter_registers;
+ return gen_rtx_REG (DImode, x86_64_int_parameter_registers_ptr[n]);
}
if (ix86_function_regparm (type, function) > 0)
@@ -19569,14 +19719,14 @@
int regno = 0;
if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
regno = 2;
- return gen_rtx_REG (SImode, regno);
+ return gen_rtx_REG ((TARGET_64BIT ? DImode : SImode), regno);
}
}
if (aggregate_value_p (TREE_TYPE (type), type))
- return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8));
+ return gen_rtx_MEM ((TARGET_64BIT ? DImode : SImode), plus_constant
(stack_pointer_rtx, 8)); /* Should this be 16 for 64-bit ? */
else
- return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4));
+ return gen_rtx_MEM ((TARGET_64BIT ? DImode : SImode), plus_constant
(stack_pointer_rtx, 4)); /* Should this be 8 for 64-bit ? */
}
/* Determine whether x86_output_mi_thunk can succeed. */
@@ -19630,7 +19780,10 @@
/* Put the this parameter into %eax. */
xops[0] = this;
xops[1] = this_reg = gen_rtx_REG (Pmode, 0);
+ if(Pmode==SImode)
output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
+ else
+ output_asm_insn ("mov{q}\t{%0, %1|%1, %0}", xops);
}
else
this_reg = NULL_RTX;
@@ -19667,7 +19820,7 @@
if (lookup_attribute ("fastcall",
TYPE_ATTRIBUTES (TREE_TYPE (function))))
tmp_regno = 0 /* EAX */;
- tmp = gen_rtx_REG (SImode, tmp_regno);
+ tmp = gen_rtx_REG ((TARGET_64BIT ? DImode : SImode), tmp_regno);
}
xops[0] = gen_rtx_MEM (Pmode, this_reg);
@@ -19735,7 +19888,7 @@
else
#endif /* TARGET_MACHO */
{
- tmp = gen_rtx_REG (SImode, 2 /* ECX */);
+ tmp = gen_rtx_REG ((TARGET_64BIT ? DImode : SImode), 2 /* ECX
*/);
output_set_got (tmp, NULL_RTX);
xops[1] = tmp;
diff -ubNr -X ../../excl.txt gcc/config/i386/i386.h
../../gcc/gcc/config/i386/i386.h
--- gcc/config/i386/i386.h 2007-03-14 09:11:01.336928400 +0100
+++ ../../gcc/gcc/config/i386/i386.h 2007-03-14 08:25:38.814825100
+0100
@@ -669,7 +669,7 @@
#define SHORT_TYPE_SIZE 16
#define INT_TYPE_SIZE 32
#define FLOAT_TYPE_SIZE 32
-#define LONG_TYPE_SIZE BITS_PER_WORD
+#define LONG_TYPE_SIZE (TARGET_64BIT_MS_ABI ? 32 : BITS_PER_WORD)
#define DOUBLE_TYPE_SIZE 64
#define LONG_LONG_TYPE_SIZE 64
@@ -978,6 +978,9 @@
reg_names[i] = ""; \
for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++) \
reg_names[i] = ""; \
+ } else if(TARGET_64BIT_MS_ABI) { \
+ call_used_regs[4 /*RSI*/] = 0; \
+ call_used_regs[5 /*RDI*/] = 0; \
} \
} while (0)
@@ -1511,7 +1514,9 @@
This space can be allocated by the caller, or be a part of the
machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
which. */
-#define REG_PARM_STACK_SPACE(FNDECL) 0
+#define REG_PARM_STACK_SPACE(FNDECL) (TARGET_64BIT_MS_ABI ? 32 : 0)
+
+#define OUTGOING_REG_PARM_STACK_SPACE (TARGET_64BIT_MS_ABI ? 1 : 0)
/* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call.
@@ -1844,9 +1849,9 @@
is also used as the pic register in ELF. So for now, don't allow more
than
3 registers to be passed in registers. */
-#define REGPARM_MAX (TARGET_64BIT ? 6 : 3)
+#define REGPARM_MAX (TARGET_64BIT ? (TARGET_64BIT_MS_ABI ? 4 : 6) : 3)
-#define SSE_REGPARM_MAX (TARGET_64BIT ? 8 : (TARGET_SSE ? 3 : 0))
+#define SSE_REGPARM_MAX (TARGET_64BIT ? (TARGET_64BIT_MS_ABI ? 4 : 8) :
(TARGET_SSE ? 3 : 0))
#define MMX_REGPARM_MAX (TARGET_64BIT ? 0 : (TARGET_MMX ? 3 : 0))
diff -ubNr -X ../../excl.txt gcc/config/i386/i386.md
../../gcc/gcc/config/i386/i386.md
--- gcc/config/i386/i386.md 2007-03-12 15:33:13.701519000 +0100
+++ ../../gcc/gcc/config/i386/i386.md 2007-03-13 10:54:33.597015500
+0100
@@ -2065,7 +2065,7 @@
default:
gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
- if (get_attr_mode (insn) == MODE_SI)
+ if (get_attr_mode (insn) == MODE_SI && !TARGET_64BIT_MS_ABI)
return "mov{l}\t{%k1, %k0|%k0, %k1}";
else if (which_alternative == 2)
return "movabs{q}\t{%1, %0|%0, %1}";
@@ -19712,13 +19712,36 @@
operands[1]));
else
#endif
- emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
+ emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (Pmode,
operands[1])));
emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
DONE;
})
+(define_expand "allocate_stack64"
+ [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
+ (minus:SI (reg:DI SP_REG)
+ (match_operand:DI 1 "general_operand" "")))
+ (clobber (reg:CC FLAGS_REG))])
+ (parallel [(set (reg:DI SP_REG)
+ (minus:DI (reg:DI SP_REG) (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))])]
+ "TARGET_STACK_PROBE"
+{
+#ifdef CHECK_STACK_LIMIT
+ if (GET_CODE (operands[1]) == CONST_INT
+ && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
+ emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
+ operands[1]));
+ else
+#endif
+ emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (DImode,
+ operands[1])));
+ emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
+ DONE;
+})
+
(define_expand "builtin_setjmp_receiver"
[(label_ref (match_operand 0 "" ""))]
"!TARGET_64BIT && flag_pic"
diff -ubNr -X ../../excl.txt gcc/config/i386/i386.opt
../../gcc/gcc/config/i386/i386.opt
--- gcc/config/i386/i386.opt 2007-03-14 09:11:01.867654500 +0100
+++ ../../gcc/gcc/config/i386/i386.opt 2007-03-14 08:25:39.335475100
+0100
@@ -263,3 +263,6 @@
;; Support Athlon 3Dnow builtins
Mask(3DNOW_A)
+
+;; Support MS64 ABI
+Mask(64BIT_MS_ABI)
diff -ubNr -X ../../excl.txt gcc/config/i386/mingw32.h
../../gcc/gcc/config/i386/mingw32.h
--- gcc/config/i386/mingw32.h 2007-03-13 17:17:36.322891200 +0100
+++ ../../gcc/gcc/config/i386/mingw32.h 2007-02-28 14:51:30.160813200
+0100
@@ -21,7 +21,11 @@
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,25 @@
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 +87,12 @@
/* 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
@@ -109,6 +129,9 @@
#undef WINT_TYPE
#define WINT_TYPE "short unsigned int"
+#undef POINTER_SIZE
+#define POINTER_SIZE (TARGET_64BIT ? 64 : 32)
+
/* mingw32 uses the -mthreads option to enable thread support. */
#undef GOMP_SELF_SPECS
#define GOMP_SELF_SPECS "%{fopenmp: -mthreads}"
diff -ubNr -X ../../excl.txt gcc/config/iq2000/iq2000.h
../../gcc/gcc/config/iq2000/iq2000.h
--- gcc/config/iq2000/iq2000.h 2007-03-13 17:18:02.900312600 +0100
+++ ../../gcc/gcc/config/iq2000/iq2000.h 2007-02-28
15:21:35.064810000 +0100
@@ -375,7 +375,7 @@
#define REG_PARM_STACK_SPACE(FNDECL) 0
-#define OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 1
#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
diff -ubNr -X ../../excl.txt gcc/config/mips/mips.h
../../gcc/gcc/config/mips/mips.h
--- gcc/config/mips/mips.h 2007-03-13 17:18:45.851184500 +0100
+++ ../../gcc/gcc/config/mips/mips.h 2007-03-12 10:55:30.049481100
+0100
@@ -1807,7 +1807,7 @@
If `ACCUMULATE_OUTGOING_ARGS' is also defined, the only effect
of this macro is to determine whether the space is included in
`current_function_outgoing_args_size'. */
-#define OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 1
#define STACK_BOUNDARY (TARGET_NEWABI ? 128 : 64)
diff -ubNr -X ../../excl.txt gcc/config/mn10300/mn10300.h
../../gcc/gcc/config/mn10300/mn10300.h
--- gcc/config/mn10300/mn10300.h 2007-03-13 17:18:06.765761900
+0100
+++ ../../gcc/gcc/config/mn10300/mn10300.h 2007-02-28
14:53:10.904457500 +0100
@@ -529,7 +529,7 @@
/* We use d0/d1 for passing parameters, so allocate 8 bytes of space
for a register flushback area. */
#define REG_PARM_STACK_SPACE(DECL) 8
-#define OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 1
#define ACCUMULATE_OUTGOING_ARGS 1
/* So we can allocate space for return pointers once for the function
diff -ubNr -X ../../excl.txt gcc/config/mt/mt.h
../../gcc/gcc/config/mt/mt.h
--- gcc/config/mt/mt.h 2007-03-13 17:18:04.602709600 +0100
+++ ../../gcc/gcc/config/mt/mt.h 2007-02-28 14:53:28.780161500
+0100
@@ -533,7 +533,7 @@
/* Define this if it is the responsibility of the caller to
allocate the area reserved for arguments passed in registers. */
-#define OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 1
/* The number of register assigned to holding function arguments. */
#define MT_NUM_ARG_REGS 4
diff -ubNr -X ../../excl.txt gcc/config/pa/pa.h
../../gcc/gcc/config/pa/pa.h
--- gcc/config/pa/pa.h 2007-03-13 17:18:41.414893900 +0100
+++ ../../gcc/gcc/config/pa/pa.h 2007-02-28 15:21:53.160108000
+0100
@@ -602,7 +602,7 @@
/* Define this if the above stack space is to be considered part of the
space allocated by the caller. */
-#define OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 1
/* Keep the stack pointer constant throughout the function.
This is both an optimization and a necessity: longjmp
diff -ubNr -X ../../excl.txt gcc/config/rs6000/rs6000.h
../../gcc/gcc/config/rs6000/rs6000.h
--- gcc/config/rs6000/rs6000.h 2007-03-13 17:18:20.575343700 +0100
+++ ../../gcc/gcc/config/rs6000/rs6000.h 2007-02-28
15:21:44.798418000 +0100
@@ -1277,7 +1277,7 @@
/* Define this if the above stack space is to be considered part of the
space allocated by the caller. */
-#define OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 1
/* This is the difference between the logical top of stack and the actual
sp.
diff -ubNr -X ../../excl.txt gcc/config/score/score.h
../../gcc/gcc/config/score/score.h
--- gcc/config/score/score.h 2007-03-13 17:18:28.556661100 +0100
+++ ../../gcc/gcc/config/score/score.h 2007-02-28 14:54:34.834041500
+0100
@@ -534,7 +534,7 @@
If `ACCUMULATE_OUTGOING_ARGS' is also defined, the only effect
of this macro is to determine whether the space is included in
`current_function_outgoing_args_size'. */
-#define OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 1
#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
diff -ubNr -X ../../excl.txt gcc/config/spu/spu.h
../../gcc/gcc/config/spu/spu.h
--- gcc/config/spu/spu.h 2007-03-13 17:17:16.615142400 +0100
+++ ../../gcc/gcc/config/spu/spu.h 2007-02-28 15:21:03.340458000
+0100
@@ -337,7 +337,7 @@
#define REG_PARM_STACK_SPACE(FNDECL) 0
-#define OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 1
#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) (0)
diff -ubNr -X ../../excl.txt gcc/config/v850/v850.h
../../gcc/gcc/config/v850/v850.h
--- gcc/config/v850/v850.h 2007-03-13 17:18:59.911121300 +0100
+++ ../../gcc/gcc/config/v850/v850.h 2007-02-28 14:55:11.945925500
+0100
@@ -626,7 +626,7 @@
/* Define this if the above stack space is to be considered part of the
space allocated by the caller. */
-#define OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 1
/* 1 if N is a possible register number for function argument passing. */
diff -ubNr -X ../../excl.txt gcc/config.build ../../gcc/gcc/config.build
--- gcc/config.build 2007-03-12 15:36:49.301038500 +0100
+++ ../../gcc/gcc/config.build 2007-01-10 11:35:30.000000000 +0100
@@ -77,7 +77,7 @@
build_xm_file=i386/xm-cygwin.h
build_exeext=.exe
;;
- i[34567]86-*-mingw32*)
+ i[34567]86-*-mingw32* | x86_64-*-mingw32)
build_xm_file=i386/xm-mingw32.h
build_exeext=.exe
;;
diff -ubNr -X ../../excl.txt gcc/config.gcc ../../gcc/gcc/config.gcc
--- gcc/config.gcc 2007-03-12 15:36:41.760496500 +0100
+++ ../../gcc/gcc/config.gcc 2007-03-13 10:54:45.193544300 +0100
@@ -1343,7 +1343,7 @@
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"
diff -ubNr -X ../../excl.txt gcc/config.host ../../gcc/gcc/config.host
--- gcc/config.host 2007-03-12 15:36:42.591658500 +0100
+++ ../../gcc/gcc/config.host 2007-03-02 08:12:17.372895800 +0100
@@ -168,7 +168,7 @@
host_xmake_file="${host_xmake_file} i386/x-cygwin"
host_exeext=.exe
;;
- i[34567]86-*-mingw32*)
+ i[34567]86-*-mingw32* | x86_64-*-mingw32*)
host_xm_file=i386/xm-mingw32.h
host_xmake_file="${host_xmake_file} i386/x-mingw32"
host_exeext=.exe
diff -ubNr -X ../../excl.txt gcc/doc/tm.texi ../../gcc/gcc/doc/tm.texi
--- gcc/doc/tm.texi 2007-03-12 11:48:46.727669400 +0100
+++ ../../gcc/gcc/doc/tm.texi 2007-03-12 10:52:12.499986600 +0100
@@ -3730,7 +3730,7 @@
@c something, not sure if it looks good. --mew 10feb93
@defmac OUTGOING_REG_PARM_STACK_SPACE
-Define this if it is the responsibility of the caller to allocate the
area
+Define this to one if it is the responsibility of the caller to allocate
the area
reserved for arguments passed in registers.
If @code{ACCUMULATE_OUTGOING_ARGS} is defined, this macro controls
@@ -9719,6 +9719,18 @@
@samp{#pragma pack()} (that is, a small power of two).
@end defmac
+@findex #pragma
+@findex pragma
+@defmac HANDLE_PRAGMA_PUSH_POP_MACRO
+Define this macro if you want to support the Win32 style pragmas
+@samp{#pragma push_macro(macro-name-as-string)} and @samp{#pragma
+pop_macro(macro-name-as-string)}. The @samp{#pragma push_macro(
+macro-name-as-string)} pragma saves the named macro and via
+@samp{#pragma pop_macro(macro-name-as-string)} it will return to the
+previous value.
+@end defmac
+
+
@defmac DOLLARS_IN_IDENTIFIERS
Define this macro to control use of the character @samp{$} in
identifier names for the C family of languages. 0 means @samp{$} is
diff -ubNr -X ../../excl.txt gcc/expr.c ../../gcc/gcc/expr.c
--- gcc/expr.c 2007-03-13 17:14:46.598320900 +0100
+++ ../../gcc/gcc/expr.c 2007-03-02 14:50:25.697905000 +0100
@@ -54,6 +54,10 @@
#include "target.h"
#include "timevar.h"
+#ifndef OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 0
+#endif
+
/* Decide whether a function's arguments should be processed
from first to last or from last to first.
@@ -1237,8 +1241,8 @@
/* If registers go on the stack anyway, any argument is sure to clobber
an outgoing argument. */
-#if defined (REG_PARM_STACK_SPACE) && defined
(OUTGOING_REG_PARM_STACK_SPACE)
- {
+#if defined (REG_PARM_STACK_SPACE)
+ if(OUTGOING_REG_PARM_STACK_SPACE) {
tree fn = emit_block_move_libcall_fn (false);
(void) fn;
if (REG_PARM_STACK_SPACE (fn) != 0)
diff -ubNr -X ../../excl.txt gcc/function.c ../../gcc/gcc/function.c
--- gcc/function.c 2007-03-13 17:16:06.399668000 +0100
+++ ../../gcc/gcc/function.c 2007-03-07 12:10:14.732360700 +0100
@@ -65,6 +65,11 @@
#include "predict.h"
#include "vecprim.h"
+#ifndef OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 0
+#endif
+
+
#ifndef LOCAL_ALIGNMENT
#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
#endif
@@ -1211,12 +1216,11 @@
`current_function_outgoing_args_size'. Nevertheless, we must allow
for it when allocating stack dynamic objects. */
-#if defined(REG_PARM_STACK_SPACE) && !
defined(OUTGOING_REG_PARM_STACK_SPACE)
+#if defined(REG_PARM_STACK_SPACE)
#define STACK_DYNAMIC_OFFSET(FNDECL) \
((ACCUMULATE_OUTGOING_ARGS \
- ? (current_function_outgoing_args_size + REG_PARM_STACK_SPACE (FNDECL))
: 0)\
+ ? (current_function_outgoing_args_size + (OUTGOING_REG_PARM_STACK_SPACE
? 0 : REG_PARM_STACK_SPACE (FNDECL))) : 0)\
+ (STACK_POINTER_OFFSET)) \
-
#else
#define STACK_DYNAMIC_OFFSET(FNDECL) \
((ACCUMULATE_OUTGOING_ARGS ? current_function_outgoing_args_size : 0) \
diff -ubNr -X ../../excl.txt gcc/unwind-generic.h
../../gcc/gcc/unwind-generic.h
--- gcc/unwind-generic.h 2007-03-13 17:16:54.654724500 +0100
+++ ../../gcc/gcc/unwind-generic.h 2007-03-01 15:33:23.362035800
+0100
@@ -252,8 +252,13 @@
typedef long long _sleb128_t;
typedef unsigned long long _uleb128_t;
#else
+#ifdef _WIN64
+ typedef int _sleb128_t __attribute__ ((mode (TI)));
+ typedef unsigned int _uleb128_t __attribute__ ((mode (TI)));
+#else
#error "long long data type is needed to define _sleb128_t"
#endif
+#endif
#else
typedef long _sleb128_t;
typedef unsigned long _uleb128_t;
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: diff.gcc.txt
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20070316/4a42e32b/attachment.txt>
More information about the Gcc-patches
mailing list