aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@gcc.gnu.org>2001-09-14 10:19:04 -0700
committerRichard Henderson <rth@gcc.gnu.org>2001-09-14 10:19:04 -0700
commit623fe81066f932745d250dcc395b4c0a0cf9fd86 (patch)
tree4433288b0c7345e569de6a64ca440004fe0e54ae /gcc
parent0e1f7b2a8fa2e23f39b8484becae19215b50148f (diff)
downloadgcc-623fe81066f932745d250dcc395b4c0a0cf9fd86.zip
gcc-623fe81066f932745d250dcc395b4c0a0cf9fd86.tar.gz
gcc-623fe81066f932745d250dcc395b4c0a0cf9fd86.tar.bz2
i386.c (internal_label_prefix): New.
* config/i386/i386.c (internal_label_prefix): New. (internal_label_prefix_len): New. (override_options): Set them. (local_symbolic_operand): New. (legitimate_pic_address_disp_p): Use it. (legitimize_pic_address): Likewise. From-SVN: r45605
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/i386/i386.c76
2 files changed, 70 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fddedfa..390310d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2001-09-14 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (internal_label_prefix): New.
+ (internal_label_prefix_len): New.
+ (override_options): Set them.
+ (local_symbolic_operand): New.
+ (legitimate_pic_address_disp_p): Use it.
+ (legitimize_pic_address): Likewise.
+
2001-09-14 Marc Espie <espie@openbsd.org>
* config/i386/unix.h (ASM_OUTPUT_MI_THUNK): Generate reference to GOT
@@ -142,7 +151,7 @@
sparc_flat_function_epilogue): Likewise.
2001-09-13 Markus Werle <numerical.simulation@web.de>
- Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+ Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
* doc/install.texi (Binaries): Add "Binaries for HP-UX 11.00 at
Aachen University of Technology".
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 6caf854..35c9dcf 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -579,7 +579,12 @@ const char *ix86_branch_cost_string;
/* Power of two alignment for functions. */
const char *ix86_align_funcs_string;
+
+/* Prefix built by ASM_GENERATE_INTERNAL_LABEL. */
+static char internal_label_prefix[16];
+static int internal_label_prefix_len;
+static int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
static void output_pic_addr_const PARAMS ((FILE *, rtx, int));
static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
int, int, FILE *));
@@ -948,6 +953,15 @@ override_options ()
&& !(target_flags & MASK_NO_ACCUMULATE_OUTGOING_ARGS)
&& !optimize_size)
target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
+
+ /* Figure out what ASM_GENERATE_INTERNAL_LABEL builds as a prefix. */
+ {
+ char *p;
+ ASM_GENERATE_INTERNAL_LABEL (internal_label_prefix, "LX", 0);
+ p = strchr (internal_label_prefix, 'X');
+ internal_label_prefix_len = p - internal_label_prefix;
+ *p = '\0';
+ }
}
void
@@ -1530,6 +1544,41 @@ pic_symbolic_operand (op, mode)
return 0;
}
+/* Return true if OP is a symbolic operand that resolves locally. */
+
+static int
+local_symbolic_operand (op, mode)
+ rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ if (GET_CODE (op) == LABEL_REF)
+ return 1;
+
+ if (GET_CODE (op) == CONST
+ && GET_CODE (XEXP (op, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
+ op = XEXP (XEXP (op, 0), 0);
+
+ if (GET_CODE (op) != SYMBOL_REF)
+ return 0;
+
+ /* These we've been told are local by varasm and encode_section_info
+ respectively. */
+ if (CONSTANT_POOL_ADDRESS_P (op) || SYMBOL_REF_FLAG (op))
+ return 1;
+
+ /* There is, however, a not insubstantial body of code in the rest of
+ the compiler that assumes it can just stick the results of
+ ASM_GENERATE_INTERNAL_LABEL in a symbol_ref and have done. */
+ /* ??? This is a hack. Should update the body of the compiler to
+ always create a DECL an invoke ENCODE_SECTION_INFO. */
+ if (strncmp (XSTR (op, 0), internal_label_prefix,
+ internal_label_prefix_len) == 0)
+ return 1;
+
+ return 0;
+}
+
/* Test for a valid operand for a call instruction. Don't allow the
arg pointer register or virtual regs since they may decay into
reg + const, which the patterns can't handle. */
@@ -3218,15 +3267,16 @@ legitimate_pic_address_disp_p (disp)
return 0;
/* Must be @GOT or @GOTOFF. */
- if (XINT (disp, 1) != 6
- && XINT (disp, 1) != 7)
- return 0;
-
- if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
- && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF)
- return 0;
+ switch (XINT (disp, 1))
+ {
+ case 6: /* @GOT */
+ return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;
- return 1;
+ case 7: /* @GOTOFF */
+ return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
+ }
+
+ return 0;
}
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a valid
@@ -3471,10 +3521,7 @@ legitimize_pic_address (orig, reg)
rtx new = orig;
rtx base;
- if (GET_CODE (addr) == LABEL_REF
- || (GET_CODE (addr) == SYMBOL_REF
- && (CONSTANT_POOL_ADDRESS_P (addr)
- || SYMBOL_REF_FLAG (addr))))
+ if (local_symbolic_operand (addr, Pmode))
{
/* This symbol may be referenced via a displacement from the PIC
base address (@GOTOFF). */
@@ -3526,10 +3573,7 @@ legitimize_pic_address (orig, reg)
/* Check first to see if this is a constant offset from a @GOTOFF
symbol reference. */
- if ((GET_CODE (op0) == LABEL_REF
- || (GET_CODE (op0) == SYMBOL_REF
- && (CONSTANT_POOL_ADDRESS_P (op0)
- || SYMBOL_REF_FLAG (op0))))
+ if (local_symbolic_operand (op0, Pmode)
&& GET_CODE (op1) == CONST_INT)
{
current_function_uses_pic_offset_table = 1;