aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-10-02 10:59:42 +0000
committerJan Hubicka <jh@suse.cz>2001-10-02 10:59:42 +0000
commit8148512e2464b497167eefb17140c5c4938e1554 (patch)
tree70110e347db132c6e0f4f51554c0c0348a6fc741
parent29155032d2246c7eee9def6ef999dce715751119 (diff)
* doc/invoke.texi (i386 Options): Document x86-64 options.
(i386 and x86-64 Options): Rename i386 options section. * config/i386/i386.h (TARGET_UNWIND_INFO): New. (TARGET_SWITCHES): Add -munwind-info. (MASK_NO_UNWIND_INFO): New. (NO_BUILTIN_SIZE_TYPE, NO_BUILTIN_PTRDIFF_TYPE): Define for biarch compilation. (ASM_OUTPUT_DOUBLE_INT): New. * config/i386/linux64.h: New spec file for Linux x86-64 support. * config.gcc: Fix tm_file settings for x86-64. * config/i386/x86-64.h: New file with OS independent x86-64 definitions. * config/i386/biarch64.h: New file used to configure compiler to biarch/64bit compilation. * config/i386/i386.c: (override_options): Set flags default for 64bit compilation. * i386.c (legitimize_pic_address): Add missing bits of 64bit support. (ix86_expand_int_movcc): Optimize DImode conditional moves with constants on x86_64. (ix86_attr_length_immediate_default): Support MODE_DI. * i386.md (fixdi splitter): Add missing "&& 1" in splitter condition. (indirect_jump, tablejump): Turn into expander. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@45946 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog34
-rw-r--r--gcc/config.gcc15
-rw-r--r--gcc/config/i386/att.h1
-rw-r--r--gcc/config/i386/biarch64.h25
-rw-r--r--gcc/config/i386/i386.c179
-rw-r--r--gcc/config/i386/i386.h12
-rw-r--r--gcc/config/i386/i386.md28
-rw-r--r--gcc/config/i386/linux64.h48
-rw-r--r--gcc/config/i386/x86-64.h118
-rw-r--r--gcc/doc/invoke.texi40
10 files changed, 430 insertions, 70 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 72e101e6d4f..5f4c223b497 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,37 @@
+Tue Oct 2 12:46:01 CEST 2001 Bo Thorsen <bo@suse.co.uk>,
+ Andreas Jaeger <aj@suse.de>,
+ Jan Hubicka <jh@suse.cz>
+
+ * doc/invoke.texi (i386 Options): Document x86-64 options.
+ (i386 and x86-64 Options): Rename i386 options section.
+
+ * config/i386/i386.h (TARGET_UNWIND_INFO): New.
+ (TARGET_SWITCHES): Add -munwind-info.
+ (MASK_NO_UNWIND_INFO): New.
+ (NO_BUILTIN_SIZE_TYPE, NO_BUILTIN_PTRDIFF_TYPE): Define for
+ biarch compilation.
+ (ASM_OUTPUT_DOUBLE_INT): New.
+
+ * config/i386/linux64.h: New spec file for Linux x86-64 support.
+ * config.gcc: Fix tm_file settings for x86-64.
+ * config/i386/x86-64.h: New file with OS independent x86-64
+ definitions.
+ * config/i386/biarch64.h: New file used to configure compiler
+ to biarch/64bit compilation.
+
+ * config/i386/i386.c: (override_options): Set flags default
+ for 64bit compilation.
+
+Tue Oct 2 12:46:01 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (legitimize_pic_address): Add missing bits of 64bit support.
+ (ix86_expand_int_movcc): Optimize DImode conditional moves with
+ constants on x86_64.
+ (ix86_attr_length_immediate_default): Support MODE_DI.
+ * i386.md (fixdi splitter): Add missing "&& 1" in splitter
+ condition.
+ (indirect_jump, tablejump): Turn into expander.
+
2001-10-02 Joseph S. Myers <jsm28@cam.ac.uk>
* c-common.c (c_format_attribute_table): Make format and
diff --git a/gcc/config.gcc b/gcc/config.gcc
index d501991ee43..df86a7b937f 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -222,6 +222,9 @@ c*-convex-*)
i[34567]86-*-*)
cpu_type=i386
;;
+x86_64-*-*)
+ cpu_type=i386
+ ;;
hppa*-*-* | parisc*-*-*)
cpu_type=pa
;;
@@ -1140,6 +1143,18 @@ i[34567]86-*-linux*) # Intel 80386's running GNU/Linux
thread_file='posix'
fi
;;
+x86_64-*-linux*)
+ xmake_file=x-linux
+ tm_file="i386/biarch64.h i386/i386.h i386/att.h linux.h i386/x86-64.h \
+ i386/linux64.h"
+ tmake_file="t-slibgcc-elf-ver t-linux i386/t-crtstuff"
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+ gnu_ld=yes
+ float_format=i386
+ if test x$enable_threads = xyes; then
+ thread_file='posix'
+ fi
+ ;;
i[34567]86-*-gnu*)
float_format=i386
;;
diff --git a/gcc/config/i386/att.h b/gcc/config/i386/att.h
index b41218e387f..8f2a1ebb50d 100644
--- a/gcc/config/i386/att.h
+++ b/gcc/config/i386/att.h
@@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_SHORT "\t.value\t"
#define ASM_LONG "\t.long\t"
+#define ASM_QUAD "\t.quad\t"
/* How to output an ASCII string constant. */
diff --git a/gcc/config/i386/biarch64.h b/gcc/config/i386/biarch64.h
new file mode 100644
index 00000000000..e2a5d917f80
--- /dev/null
+++ b/gcc/config/i386/biarch64.h
@@ -0,0 +1,25 @@
+/* Make configure files to produce biarch compiler defaulting to 64bit mode.
+ This file must be included very first, while the OS specific file later
+ to overwrite otherwise wrong defaults.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Bo Thorsen <bo@suse.de>.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#define TARGET_64BIT_DEFAULT
+#define TARGET_BI_ARCH
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 75e19682dde..7e65b0e9164 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -984,6 +984,16 @@ override_options ()
if (flag_unsafe_math_optimizations)
target_flags &= ~MASK_IEEE_FP;
+ 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.");
+ /* Enable by default the SSE and MMX builtins. */
+ target_flags |= MASK_SSE2 | MASK_SSE | MASK_MMX | MASK_128BIT_LONG_DOUBLE;
+ }
+
/* It makes no sense to ask for just SSE builtins, so MMX is also turned
on by -msse. */
if (TARGET_SSE)
@@ -2214,7 +2224,7 @@ ix86_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
emit_insn (gen_rtx_SET(VOIDmode, tmp_reg,
plus_constant (save_area, 8 * REGPARM_MAX + 127)));
mem = gen_rtx_MEM (BLKmode, plus_constant (tmp_reg, -127));
- set_mem_alias_set(mem, set);
+ set_mem_alias_set (mem, set);
/* And finally do the dirty job! */
emit_insn (gen_sse_prologue_save (mem, nsse_reg, GEN_INT (next_cum.sse_regno),
@@ -2260,7 +2270,7 @@ ix86_va_start (stdarg_p, valist, nextarg)
if (TARGET_DEBUG_ARG)
fprintf (stderr, "va_start: words = %d, n_gpr = %d, n_fpr = %d\n",
- words, n_gpr, n_fpr);
+ (int)words, (int)n_gpr, (int)n_fpr);
t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
build_int_2 (n_gpr * 8, 0));
@@ -4735,37 +4745,63 @@ legitimize_pic_address (orig, reg)
if (local_symbolic_operand (addr, Pmode))
{
- /* This symbol may be referenced via a displacement from the PIC
- base address (@GOTOFF). */
+ /* In 64bit mode we can address such objects directly. */
+ if (TARGET_64BIT)
+ new = addr;
+ else
+ {
+ /* This symbol may be referenced via a displacement from the PIC
+ base address (@GOTOFF). */
- current_function_uses_pic_offset_table = 1;
- new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 7);
- new = gen_rtx_CONST (Pmode, new);
- new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
+ current_function_uses_pic_offset_table = 1;
+ new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 7);
+ new = gen_rtx_CONST (Pmode, new);
+ new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
- if (reg != 0)
- {
- emit_move_insn (reg, new);
- new = reg;
- }
+ if (reg != 0)
+ {
+ emit_move_insn (reg, new);
+ new = reg;
+ }
+ }
}
else if (GET_CODE (addr) == SYMBOL_REF)
{
- /* This symbol must be referenced via a load from the
- Global Offset Table (@GOT). */
+ if (TARGET_64BIT)
+ {
+ current_function_uses_pic_offset_table = 1;
+ new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 15);
+ new = gen_rtx_CONST (Pmode, new);
+ new = gen_rtx_MEM (Pmode, new);
+ RTX_UNCHANGING_P (new) = 1;
+ set_mem_alias_set (new, ix86_GOT_alias_set ());
+
+ if (reg == 0)
+ reg = gen_reg_rtx (Pmode);
+ /* Use directly gen_movsi, otherwise the address is loaded
+ into register for CSE. We don't want to CSE this addresses,
+ instead we CSE addresses from the GOT table, so skip this. */
+ emit_insn (gen_movsi (reg, new));
+ new = reg;
+ }
+ else
+ {
+ /* This symbol must be referenced via a load from the
+ Global Offset Table (@GOT). */
- current_function_uses_pic_offset_table = 1;
- new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 6);
- new = gen_rtx_CONST (Pmode, new);
- new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
- new = gen_rtx_MEM (Pmode, new);
- RTX_UNCHANGING_P (new) = 1;
- set_mem_alias_set (new, ix86_GOT_alias_set ());
+ current_function_uses_pic_offset_table = 1;
+ new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 6);
+ new = gen_rtx_CONST (Pmode, new);
+ new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
+ new = gen_rtx_MEM (Pmode, new);
+ RTX_UNCHANGING_P (new) = 1;
+ set_mem_alias_set (new, ix86_GOT_alias_set ());
- if (reg == 0)
- reg = gen_reg_rtx (Pmode);
- emit_move_insn (reg, new);
- new = reg;
+ if (reg == 0)
+ reg = gen_reg_rtx (Pmode);
+ emit_move_insn (reg, new);
+ new = reg;
+ }
}
else
{
@@ -5141,7 +5177,13 @@ i386_dwarf_output_addr_const (file, x)
FILE *file;
rtx x;
{
+#ifdef ASM_QUAD
+ fprintf (file, "%s", TARGET_64BIT ? ASM_QUAD : INT_ASM_OP);
+#else
+ if (TARGET_64BIT)
+ abort ();
fprintf (file, "%s", INT_ASM_OP);
+#endif
if (flag_pic)
output_pic_addr_const (file, x, '\0');
else
@@ -7823,7 +7865,7 @@ ix86_expand_int_movcc (operands)
HImode insns, we'd be swallowed in word prefix ops. */
if (GET_MODE (operands[0]) != HImode
- && GET_MODE (operands[0]) != DImode
+ && (GET_MODE (operands[0]) != DImode || TARGET_64BIT)
&& GET_CODE (operands[2]) == CONST_INT
&& GET_CODE (operands[3]) == CONST_INT)
{
@@ -7852,10 +7894,13 @@ ix86_expand_int_movcc (operands)
if (reg_overlap_mentioned_p (out, ix86_compare_op0)
|| reg_overlap_mentioned_p (out, ix86_compare_op1))
- tmp = gen_reg_rtx (SImode);
+ tmp = gen_reg_rtx (GET_MODE (operands[0]));
emit_insn (compare_seq);
- emit_insn (gen_x86_movsicc_0_m1 (tmp));
+ if (GET_MODE (tmp) == DImode)
+ emit_insn (gen_x86_movdicc_0_m1_rex64 (tmp));
+ else
+ emit_insn (gen_x86_movsicc_0_m1 (tmp));
if (diff == 1)
{
@@ -7867,7 +7912,12 @@ ix86_expand_int_movcc (operands)
* Size 5 - 8.
*/
if (ct)
- emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (ct)));
+ {
+ if (GET_MODE (tmp) == DImode)
+ emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (ct)));
+ else
+ emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (ct)));
+ }
}
else if (cf == -1)
{
@@ -7878,7 +7928,10 @@ ix86_expand_int_movcc (operands)
*
* Size 8.
*/
- emit_insn (gen_iorsi3 (tmp, tmp, GEN_INT (ct)));
+ if (GET_MODE (tmp) == DImode)
+ emit_insn (gen_iordi3 (tmp, tmp, GEN_INT (ct)));
+ else
+ emit_insn (gen_iorsi3 (tmp, tmp, GEN_INT (ct)));
}
else if (diff == -1 && ct)
{
@@ -7890,9 +7943,18 @@ ix86_expand_int_movcc (operands)
*
* Size 8 - 11.
*/
- emit_insn (gen_one_cmplsi2 (tmp, tmp));
- if (cf)
- emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (cf)));
+ if (GET_MODE (tmp) == DImode)
+ {
+ emit_insn (gen_one_cmpldi2 (tmp, tmp));
+ if (cf)
+ emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (cf)));
+ }
+ else
+ {
+ emit_insn (gen_one_cmplsi2 (tmp, tmp));
+ if (cf)
+ emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (cf)));
+ }
}
else
{
@@ -7904,10 +7966,20 @@ ix86_expand_int_movcc (operands)
*
* Size 8 - 11.
*/
- emit_insn (gen_andsi3 (tmp, tmp, GEN_INT (trunc_int_for_mode
- (cf - ct, SImode))));
- if (ct)
- emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (ct)));
+ if (GET_MODE (tmp) == DImode)
+ {
+ emit_insn (gen_anddi3 (tmp, tmp, GEN_INT (trunc_int_for_mode
+ (cf - ct, DImode))));
+ if (ct)
+ emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (ct)));
+ }
+ else
+ {
+ emit_insn (gen_andsi3 (tmp, tmp, GEN_INT (trunc_int_for_mode
+ (cf - ct, SImode))));
+ if (ct)
+ emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (ct)));
+ }
}
if (tmp != out)
@@ -7961,43 +8033,28 @@ ix86_expand_int_movcc (operands)
/* On x86_64 the lea instruction operates on Pmode, so we need to get arithmetics
done in proper mode to match. */
if (diff == 1)
- {
- if (Pmode != SImode)
- tmp = gen_lowpart (Pmode, out);
- else
- tmp = out;
- }
+ tmp = out;
else
{
rtx out1;
- if (Pmode != SImode)
- out1 = gen_lowpart (Pmode, out);
- else
- out1 = out;
- tmp = gen_rtx_MULT (Pmode, out1, GEN_INT (diff & ~1));
+ out1 = out;
+ tmp = gen_rtx_MULT (GET_MODE (out), out1, GEN_INT (diff & ~1));
nops++;
if (diff & 1)
{
- tmp = gen_rtx_PLUS (Pmode, tmp, out1);
+ tmp = gen_rtx_PLUS (GET_MODE (out), tmp, out1);
nops++;
}
}
if (cf != 0)
{
- tmp = gen_rtx_PLUS (Pmode, tmp, GEN_INT (cf));
+ tmp = gen_rtx_PLUS (GET_MODE (out), tmp, GEN_INT (cf));
nops++;
}
if (tmp != out
&& (GET_CODE (tmp) != SUBREG || SUBREG_REG (tmp) != out))
{
- if (Pmode != SImode)
- tmp = gen_rtx_SUBREG (SImode, tmp, 0);
-
- /* ??? We should to take care for outputing non-lea arithmetics
- for Pmode != SImode case too, but it is quite tricky and not
- too important, since all TARGET_64BIT machines support real
- conditional moves. */
- if (nops == 1 && Pmode == SImode)
+ if (nops == 1)
{
rtx clob;
@@ -9694,6 +9751,10 @@ ix86_attr_length_immediate_default (insn, shortform)
case MODE_SI:
len+=4;
break;
+ /* Immediates for DImode instructions are encoded as 32bit sign extended values. */
+ case MODE_DI:
+ len+=4;
+ break;
default:
fatal_insn ("Unknown insn mode", insn);
}
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index fc6f1c93861..174c59452a0 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -484,6 +484,11 @@ extern int ix86_arch;
#endif
#endif /* CPP_CPU_DEFAULT_SPEC */
+#ifdef TARGET_BI_ARCH
+#define NO_BUILTIN_SIZE_TYPE
+#define NO_BUILTIN_PTRDIFF_TYPE
+#endif
+
#ifdef NO_BUILTIN_SIZE_TYPE
#define CPP_CPU32_SIZE_TYPE_SPEC \
" -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int"
@@ -653,7 +658,7 @@ extern int ix86_arch;
the stack, which results in aligned frames for functions called from
main, though it does nothing for the alignment of main itself. */
#define FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN \
- (ix86_preferred_stack_boundary > STACK_BOUNDARY)
+ (ix86_preferred_stack_boundary > STACK_BOUNDARY && !TARGET_64BIT)
/* Allocation boundary for the code of a function. */
#define FUNCTION_BOUNDARY 16
@@ -2910,6 +2915,11 @@ do { long l; \
output_addr_const (FILE,(VALUE)), \
putc('\n',FILE))
+#define ASM_OUTPUT_DOUBLE_INT(FILE,VALUE) \
+( fprintf (FILE, "%s\t", ASM_QUAD), \
+ output_addr_const (FILE,(VALUE)), \
+ putc('\n',FILE))
+
/* Likewise for `char' and `short' constants. */
#define ASM_OUTPUT_SHORT(FILE,VALUE) \
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 3b98788b67a..c2e05cb8d92 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -4688,7 +4688,7 @@
&& !reload_completed && !reload_in_progress
&& (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
"#"
- ""
+ "&& 1"
[(const_int 0)]
{
operands[2] = assign_386_stack_local (HImode, 1);
@@ -12956,9 +12956,21 @@
"jmp\t%l0"
[(set_attr "type" "ibr")])
-(define_insn "indirect_jump"
- [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
+(define_expand "indirect_jump"
+ [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
""
+ "")
+
+(define_insn "*indirect_jump"
+ [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
+ "!TARGET_64BIT"
+ "jmp\t%A0"
+ [(set_attr "type" "ibr")
+ (set_attr "length_immediate" "0")])
+
+(define_insn "*indirect_jump_rtx64"
+ [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
+ "TARGET_64BIT"
"jmp\t%A0"
[(set_attr "type" "ibr")
(set_attr "length_immediate" "0")])
@@ -12989,7 +13001,15 @@
(define_insn "*tablejump_1"
[(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
(use (label_ref (match_operand 1 "" "")))]
- ""
+ "!TARGET_64BIT"
+ "jmp\t%A0"
+ [(set_attr "type" "ibr")
+ (set_attr "length_immediate" "0")])
+
+(define_insn "*tablejump_1_rtx64"
+ [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
+ (use (label_ref (match_operand 1 "" "")))]
+ "TARGET_64BIT"
"jmp\t%A0"
[(set_attr "type" "ibr")
(set_attr "length_immediate" "0")])
diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h
new file mode 100644
index 00000000000..529c3014290
--- /dev/null
+++ b/gcc/config/i386/linux64.h
@@ -0,0 +1,48 @@
+/* Definitions for AMD x86-64 running Linux-based GNU systems with ELF format.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Jan Hubicka <jh@suse.cz>, based on linux.h.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#define LINUX_DEFAULT_ELF
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (x86-64 Linux/ELF)");
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dlinux -Asystem(posix)"
+
+#undef CPP_SPEC
+#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT} %{!m32:-D__LONG_MAX__=9223372036854775807L}"
+
+/* Provide a LINK_SPEC. Here we provide support for the special GCC
+ options -static and -shared, which allow us to link things in one
+ of these three modes by applying the appropriate combinations of
+ options at link-time.
+
+ When the -shared link option is used a final link is not being
+ done. */
+
+#undef LINK_SPEC
+#define LINK_SPEC "%{!m32:-m elf_x86_64} %{m32:-m elf_i386} {shared:-shared} \
+ %{!shared: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld64.so.1}} \
+ %{static:-static}}"
+
diff --git a/gcc/config/i386/x86-64.h b/gcc/config/i386/x86-64.h
new file mode 100644
index 00000000000..baf5b2488dc
--- /dev/null
+++ b/gcc/config/i386/x86-64.h
@@ -0,0 +1,118 @@
+/* OS independent definitions for AMD x86-64.
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Contributed by Bo Thorsen <bo@suse.de>.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* The svr4 ABI for the i386 says that records and unions are returned
+ in memory. */
+#undef DEFAULT_PCC_STRUCT_RETURN
+#define DEFAULT_PCC_STRUCT_RETURN 1
+
+#undef ASM_COMMENT_START
+#define ASM_COMMENT_START "#"
+
+/* This is how to output an element of a case-vector that is relative.
+ This is only used for PIC code. See comments by the `casesi' insn in
+ i386.md for an explanation of the expression this outputs. */
+#undef ASM_OUTPUT_ADDR_DIFF_ELT
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
+ if (TARGET_64BIT) \
+ fprintf (FILE, "\t.long %s%d-.+4+(.-%s%d)\n", LPREFIX, VALUE, LPREFIX, REL); \
+ else \
+ fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE)
+
+/* Indicate that jump tables go in the text section. This is
+ necessary when compiling PIC code. */
+#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic && !TARGET_64BIT)
+
+#undef DBX_REGISTER_NUMBER
+#define DBX_REGISTER_NUMBER(n) \
+ (TARGET_64BIT ? dbx64_register_map[n] : svr4_dbx_register_map[n])
+
+/* Output assembler code to FILE to call the profiler. */
+#define NO_PROFILE_COUNTERS
+
+#undef FUNCTION_PROFILER
+#define FUNCTION_PROFILER(FILE, LABELNO) \
+{ \
+ if (TARGET_64BIT && flag_pic) \
+ fprintf (FILE, "\tcall\t*mcount@PLT\n"); \
+ else if (flag_pic) \
+ fprintf (FILE, "\tcall\t*mcount@GOT(%%ebx)\n"); \
+ else \
+ fprintf (FILE, "\tcall\tmcount\n"); \
+}
+
+#undef SIZE_TYPE
+#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE 32
+
+#undef CC1_SPEC
+#define CC1_SPEC "%(cc1_cpu) %{profile:-p}"
+
+#undef ASM_SPEC
+#define ASM_SPEC "%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} \
+ %{Wa,*:%*} %{m32:--32}"
+
+/* A C statement (sans semicolon) to output to the stdio stream
+ FILE the assembler definition of uninitialized global DECL named
+ NAME whose size is SIZE bytes and alignment is ALIGN bytes.
+ Try to use asm_output_aligned_bss to implement this macro. */
+
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
+
+/* A C statement to output to the stdio stream FILE an assembler
+ command to advance the location counter to a multiple of 1<<LOG
+ bytes if it is within MAX_SKIP bytes.
+
+ This is used to align code labels according to Intel recommendations. */
+
+#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
+ do { \
+ if ((LOG) != 0) { \
+ if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
+ } \
+ } while (0)
+#endif
+
+
+/* i386 System V Release 4 uses DWARF debugging info.
+ x86-64 ABI specifies DWARF2. */
+
+#undef DWARF2_DEBUGGING_INFO
+#undef DWARF_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO
+#define DWARF2_UNWIND_INFO 1
+/* Incorrectly autodetected in cross compilation. */
+#undef HAVE_AS_DWARF2_DEBUG_LINE
+#define HAVE_AS_DWARF2_DEBUG_LINE
+
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b3a731a3266..8499d72bac6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -464,7 +464,7 @@ in the following sections.
-mabi=32 -mabi=n32 -mabi=64 -mabi=eabi @gol
-mfix7000 -mno-crt0}
-@emph{i386 Options}
+@emph{i386 and x86-64 Options}
@gccoptlist{
-mcpu=@var{cpu-type} -march=@var{cpu-type} @gol
-mintel-syntax -mieee-fp -mno-fancy-math-387 @gol
@@ -474,7 +474,9 @@ in the following sections.
-mmmx -msse -m3dnow @gol
-mthreads -mno-align-stringops -minline-all-stringops @gol
-mpush-args -maccumulate-outgoing-args -m128bit-long-double @gol
--m96bit-long-double -mregparm=@var{num} -momit-leaf-frame-pointer}
+-m96bit-long-double -mregparm=@var{num} -momit-leaf-frame-pointer @gol
+-mno-red-zone@gol
+-m32 -m64}
@emph{HPPA Options}
@gccoptlist{
@@ -5077,7 +5079,7 @@ that macro, which enables you to change the defaults.
* RS/6000 and PowerPC Options::
* RT Options::
* MIPS Options::
-* i386 Options::
+* i386 and x86-64 Options::
* HPPA Options::
* Intel 960 Options::
* DEC Alpha Options::
@@ -7418,12 +7420,15 @@ options is also defined by that macro, which enables you to change the
defaults.
@end ifset
-@node i386 Options
-@subsection Intel 386 Options
+@node i386 and x86-64 Options
+@subsection Intel 386 and AMD x86-64 Options
@cindex i386 Options
+@cindex x86-64 Options
@cindex Intel 386 Options
+@cindex AMD x86-64 Options
-These @samp{-m} options are defined for the i386 family of computers:
+These @samp{-m} options are defined for the i386 and x86-64 family of
+computers:
@table @gcctabopt
@item -mcpu=@var{cpu-type}
@@ -8027,6 +8032,29 @@ makes an extra register available in leaf functions. The option
which might make debugging harder.
@end table
+These @samp{-m} switches are supported in addition to the above
+on AMD x86-64 processors in 64-bit environments.
+
+@table @gcctabopt
+@item -m32
+@itemx -m64
+@opindex m32
+@opindex m64
+Generate code for a 32-bit or 64-bit environment.
+The 32-bit environment sets int, long and pointer to 32 bits and
+generates code that runs on any i386 system.
+The 64-bit environment sets int to 32 bits and long and pointer
+to 64 bits and generates code for AMD's x86-64 architecture.
+
+@item -mno-red-zone
+@opindex no-red-zone
+Do not use a so called red zone for x86-64 code. The red zone is mandated
+by the x86-64 ABI, it is a 128-byte area beyond the location of the
+stack pointer that will not be modified by signal or interrupt handlers
+and therefore can be used for temporary data without adjusting the stack
+pointer. The flag @option{-mno-red-zone} disables this red zone.
+@end table
+
@node HPPA Options
@subsection HPPA Options
@cindex HPPA Options