aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/m68k/m68k-protos.h1
-rw-r--r--gcc/config/m68k/m68k.c41
-rw-r--r--gcc/config/m68k/m68k.h6
-rw-r--r--gcc/config/m68k/m68k.md1
-rw-r--r--gcc/config/m68k/m68k.opt4
-rw-r--r--gcc/doc/invoke.texi35
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/m68k/xgot-1.c11
9 files changed, 111 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0cb236d6311..e7e91d7bb15 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2008-06-04 Joseph Myers <joseph@codesourcery.com>
+ Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * config/m68k/m68k.opt (mxgot): New option.
+ * config/m68k/m68k.c (legitimize_pic_address): Handle -mxgot.
+ (m68k_output_addr_const_extra): New.
+ * config/m68k/m68k.h (OUTPUT_ADDR_CONST_EXTRA): New.
+ * config/m68k/m68k-protos.h (m68k_output_addr_const_extra): Declare.
+ * config/m68k/m68k.md (UNSPEC_GOTOFF): Define.
+ * doc/invoke.texi (M680x0 Options): Document -mxgot.
+
2008-06-04 Richard Guenther <rguenther@suse.de>
* tree-ssa-structalias.c (handle_ptr_arith): Correctly handle
diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h
index 33025f8f34a..596d4ec8e03 100644
--- a/gcc/config/m68k/m68k-protos.h
+++ b/gcc/config/m68k/m68k-protos.h
@@ -50,6 +50,7 @@ extern bool strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn,
extern int standard_68881_constant_p (rtx);
extern void print_operand_address (FILE *, rtx);
extern void print_operand (FILE *, rtx, int);
+extern bool m68k_output_addr_const_extra (FILE *, rtx);
extern void notice_update_cc (rtx, rtx);
extern bool m68k_legitimate_base_reg_p (rtx, bool);
extern bool m68k_legitimate_index_reg_p (rtx, bool);
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 52a60da0664..a1437d29c36 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -2059,9 +2059,30 @@ legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
{
gcc_assert (reg);
- pic_ref = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode,
- pic_offset_table_rtx, orig));
+ if (TARGET_COLDFIRE && TARGET_XGOT)
+ /* When compiling with -mxgot switch the code for the above
+ example will look like this:
+
+ movel a5, a0
+ addl _foo@GOT, a0
+ movel a0@, a0
+ movel #12345, a0@ */
+ {
+ rtx pic_offset;
+
+ /* Wrap ORIG in UNSPEC_GOTOFF to tip m68k_output_addr_const_extra
+ to put @GOT after reference. */
+ pic_offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig),
+ UNSPEC_GOTOFF);
+ pic_offset = gen_rtx_CONST (Pmode, pic_offset);
+ emit_move_insn (reg, pic_offset);
+ emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
+ pic_ref = gen_rtx_MEM (Pmode, reg);
+ }
+ else
+ pic_ref = gen_rtx_MEM (Pmode,
+ gen_rtx_PLUS (Pmode,
+ pic_offset_table_rtx, orig));
crtl->uses_pic_offset_table = 1;
MEM_READONLY_P (pic_ref) = 1;
emit_move_insn (reg, pic_ref);
@@ -3869,6 +3890,20 @@ print_operand (FILE *file, rtx op, int letter)
}
}
+/* m68k implementation of OUTPUT_ADDR_CONST_EXTRA. */
+
+bool
+m68k_output_addr_const_extra (FILE *file, rtx x)
+{
+ if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_GOTOFF)
+ return false;
+
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ /* ??? What is the non-MOTOROLA syntax? */
+ fputs ("@GOT", file);
+ return true;
+}
+
/* A C compound statement to output to stdio stream STREAM the
assembler syntax for an instruction operand that is a memory
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 521ad849716..7a68595a334 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -1079,6 +1079,12 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
+#define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL) \
+do { \
+ if (! m68k_output_addr_const_extra (FILE, (X))) \
+ goto FAIL; \
+} while (0);
+
/* Values used in the MICROARCH argument to M68K_DEVICE. */
enum uarch_type
{
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 56c459e68b0..9effb344ec5 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -116,6 +116,7 @@
(UNSPEC_GOT 3)
(UNSPEC_IB 4)
(UNSPEC_TIE 5)
+ (UNSPEC_GOTOFF 6)
])
;; UNSPEC_VOLATILE usage:
diff --git a/gcc/config/m68k/m68k.opt b/gcc/config/m68k/m68k.opt
index 23a3c09c6c5..bc0fb2c9939 100644
--- a/gcc/config/m68k/m68k.opt
+++ b/gcc/config/m68k/m68k.opt
@@ -178,3 +178,7 @@ Do not use unaligned memory references
mtune=
Target RejectNegative Joined
Tune for the specified target CPU or architecture
+
+mxgot
+Target Report Mask(XGOT)
+Support more than 8192 GOT entries on ColdFire
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 6dbd19ea2f9..ece9d9d5fc0 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -607,7 +607,8 @@ Objective-C and Objective-C++ Dialects}.
-mnobitfield -mrtd -mno-rtd -mdiv -mno-div -mshort @gol
-mno-short -mhard-float -m68881 -msoft-float -mpcrel @gol
-malign-int -mstrict-align -msep-data -mno-sep-data @gol
--mshared-library-id=n -mid-shared-library -mno-id-shared-library}
+-mshared-library-id=n -mid-shared-library -mno-id-shared-library @gol
+-mxgot -mno-xgot}
@emph{M68hc1x Options}
@gccoptlist{-m6811 -m6812 -m68hc11 -m68hc12 -m68hcs12 @gol
@@ -11776,6 +11777,38 @@ compiled. Specifying a value of 0 will generate more compact code, specifying
other values will force the allocation of that number to the current
library but is no more space or time efficient than omitting this option.
+@item -mxgot
+@itemx -mno-xgot
+@opindex mxgot
+@opindex mno-xgot
+When generating position-independent code for ColdFire, generate code
+that works if the GOT has more than 8192 entries. This code is
+larger and slower than code generated without this option. On M680x0
+processors, this option is not needed; @option{-fPIC} suffices.
+
+GCC normally uses a single instruction to load values from the GOT@.
+While this is relatively efficient, it only works if the GOT
+is smaller than about 64k. Anything larger causes the linker
+to report an error such as:
+
+@cindex relocation truncated to fit (ColdFire)
+@smallexample
+relocation truncated to fit: R_68K_GOT16O foobar
+@end smallexample
+
+If this happens, you should recompile your code with @option{-mxgot}.
+It should then work with very large GOTs. However, code generated with
+@option{-mxgot} is less efficient, since it takes 4 instructions to fetch
+the value of a global symbol.
+
+Note that some linkers, including newer versions of the GNU linker,
+can create multiple GOTs and sort GOT entries. If you have such a linker,
+you should only need to use @option{-mxgot} when compiling a single
+object file that accesses more than 8192 GOT entries. Very few do.
+
+These options have no effect unless GCC is generating
+position-independent code.
+
@end table
@node M68hc1x Options
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d43613a3a06..a2f746c8198 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-04 Joseph Myers <joseph@codesourcery.com>
+ Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * gcc.target/m68k/xgot-1.c: New test.
+
2008-06-04 Richard Guenther <rguenther@suse.de>
* gcc.c-torture/execute/20080604-1.c: New testcase.
diff --git a/gcc/testsuite/gcc.target/m68k/xgot-1.c b/gcc/testsuite/gcc.target/m68k/xgot-1.c
new file mode 100644
index 00000000000..f7dd6c939ac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/xgot-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fpic -mxgot" } */
+/* { dg-final { scan-assembler "foo@GOT,\%\[ad\]\[0-7\]" } } */
+
+extern int foo;
+
+int
+bar (void)
+{
+ return foo;
+}