aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/m68k/m68k.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2008-06-04 12:17:50 +0000
committerJoseph Myers <joseph@codesourcery.com>2008-06-04 12:17:50 +0000
commitd8d060b871814c10555071404eb88dd7f9a6aed7 (patch)
tree34d800b5977091b32c2932a09d612fb5986fd13c /gcc/config/m68k/m68k.c
parent17086702c1afbca195ddcffabb7e8f36e86ae9ff (diff)
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. testsuite: 2008-06-04 Joseph Myers <joseph@codesourcery.com> Maxim Kuvyrkov <maxim@codesourcery.com> * gcc.target/m68k/xgot-1.c: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@136355 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/m68k/m68k.c')
-rw-r--r--gcc/config/m68k/m68k.c41
1 files changed, 38 insertions, 3 deletions
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