From: Richard Henderson Date: Fri, 14 Sep 2001 17:19:04 +0000 (-0700) Subject: i386.c (internal_label_prefix): New. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=623fe81066f932745d250dcc395b4c0a0cf9fd86;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fddedfadf11..390310d6a5f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2001-09-14 Richard Henderson + + * 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 * 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 - Gerald Pfeifer + Gerald Pfeifer * 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 6caf8540b6b..35c9dcfea1c 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;