aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-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
5 files changed, 50 insertions, 3 deletions
diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h
index 33025f8..596d4ec 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 52a60da..a1437d2 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 521ad84..7a68595 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 56c459e..9effb34 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 23a3c09..bc0fb2c 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