diff options
author | Hans-Peter Nilsson <hp@axis.com> | 2005-02-08 15:35:12 +0000 |
---|---|---|
committer | Hans-Peter Nilsson <hp@gcc.gnu.org> | 2005-02-08 15:35:12 +0000 |
commit | 453bd0f554e8afa38eab4b4f3dffd3ec1a647c09 (patch) | |
tree | 67f378a8e25e7f88e70640fb844197d14630e5c7 /gcc/config/cris | |
parent | 749c6ef9922642ee4f01a263f3803b3dcf8d850d (diff) | |
download | gcc-453bd0f554e8afa38eab4b4f3dffd3ec1a647c09.zip gcc-453bd0f554e8afa38eab4b4f3dffd3ec1a647c09.tar.gz gcc-453bd0f554e8afa38eab4b4f3dffd3ec1a647c09.tar.bz2 |
re PR target/19806 (cris-axis-elf testsuite failure: gcc.c-torture/execute/20001130-1.c compilation, -O0)
PR target/19806
* config/cris/cris.c (in_code): New variable.
(cris_output_addr_const): Now a static function, a wrapper for
output_addr_const.
(cris_asm_output_symbol_ref): New function, broken out SYMBOL_REF
case from old cris_output_addr_const.
(cris_asm_output_label_ref): Similar for LABEL_REF.
(cris_output_addr_const_extra): Similar for UNSPEC.
* config/cris/cris.h (OUTPUT_ADDR_CONST_EXTRA)
(ASM_OUTPUT_SYMBOL_REF, ASM_OUTPUT_LABEL_REF): Define.
* config/cris/cris-protos.h (cris_output_addr_const): Remove
declaration.
(cris_asm_output_symbol_ref, cris_output_addr_const_extra)
(cris_asm_output_label_ref): Declare.
From-SVN: r94738
Diffstat (limited to 'gcc/config/cris')
-rw-r--r-- | gcc/config/cris/cris-protos.h | 4 | ||||
-rw-r--r-- | gcc/config/cris/cris.c | 238 | ||||
-rw-r--r-- | gcc/config/cris/cris.h | 9 |
3 files changed, 105 insertions, 146 deletions
diff --git a/gcc/config/cris/cris-protos.h b/gcc/config/cris/cris-protos.h index f085e5d..86b0c07 100644 --- a/gcc/config/cris/cris-protos.h +++ b/gcc/config/cris/cris-protos.h @@ -42,9 +42,11 @@ extern int cris_legitimate_pic_operand (rtx); extern int cris_gotless_symbol (rtx); extern int cris_got_symbol (rtx); extern int cris_symbol (rtx); -extern void cris_output_addr_const (FILE *, rtx); +extern void cris_asm_output_symbol_ref (FILE *, rtx); +extern bool cris_output_addr_const_extra (FILE *, rtx); extern int cris_cfun_uses_pic_table (void); #endif /* RTX_CODE */ +extern void cris_asm_output_label_ref (FILE *, char *); extern void cris_target_asm_named_section (const char *, unsigned int, tree); extern int cris_return_address_on_stack (void); diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index d023d00..4756f8c 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -83,6 +83,10 @@ static char cris_output_insn_is_bound = 0; just the "sym:GOTOFF" part. */ static int cris_pic_sympart_only = 0; +/* In code for output macros, this is how we know whether e.g. constant + goes in code or in a static initializer. */ +static int in_code = 0; + /* Fix for reg_overlap_mentioned_p. */ static int cris_reg_overlap_mentioned_p (rtx, rtx); @@ -90,6 +94,8 @@ static void cris_print_base (rtx, FILE *); static void cris_print_index (rtx, FILE *); +static void cris_output_addr_const (FILE *, rtx); + static struct machine_function * cris_init_machine_status (void); static rtx cris_struct_value_rtx (tree, int); @@ -2972,178 +2978,120 @@ cris_split_movdx (rtx *operands) return val; } -/* This is in essence a copy of output_addr_const altered to output - symbolic operands as PIC. - - FIXME: Add hooks similar to ASM_OUTPUT_SYMBOL_REF to get this effect in - the "real" output_addr_const. All we need is one for LABEL_REF (and - one for CODE_LABEL?). */ +/* Use from within code, from e.g. PRINT_OPERAND and + PRINT_OPERAND_ADDRESS. Macros used in output_addr_const need to emit + different things depending on whether code operand or constant is + emitted. */ -void +static void cris_output_addr_const (FILE *file, rtx x) { - int is_plt = 0; - -restart: - switch (GET_CODE (x)) - { - case UNSPEC: - ASSERT_PLT_UNSPEC (x); - x = XVECEXP (x, 0, 0); - is_plt = 1; - - /* Fall through. */ - case SYMBOL_REF: - if (flag_pic) - { - const char *origstr = XSTR (x, 0); - const char *str; + in_code++; + output_addr_const (file, x); + in_code--; +} - str = (* targetm.strip_name_encoding) (origstr); +/* Worker function for ASM_OUTPUT_SYMBOL_REF. */ - if (is_plt) - { - if (cris_pic_sympart_only) - { - assemble_name (file, str); - fprintf (file, ":PLTG"); - } - else - { - if (TARGET_AVOID_GOTPLT) - /* We shouldn't get here. */ - abort (); +void +cris_asm_output_symbol_ref (FILE *file, rtx x) +{ + if (flag_pic && in_code > 0) + { + const char *origstr = XSTR (x, 0); + const char *str; - fprintf (file, "[$%s+", reg_names [PIC_OFFSET_TABLE_REGNUM]); - assemble_name (file, XSTR (x, 0)); + str = (* targetm.strip_name_encoding) (origstr); - if (flag_pic == 1) - fprintf (file, ":GOTPLT16]"); - else - fprintf (file, ":GOTPLT]"); - } - } - else if (cris_gotless_symbol (x)) - { - if (! cris_pic_sympart_only) - fprintf (file, "$%s+", reg_names [PIC_OFFSET_TABLE_REGNUM]); - assemble_name (file, str); - fprintf (file, ":GOTOFF"); - } - else if (cris_got_symbol (x)) - { - if (cris_pic_sympart_only) - abort (); - fprintf (file, "[$%s+", reg_names [PIC_OFFSET_TABLE_REGNUM]); - assemble_name (file, XSTR (x, 0)); + if (cris_gotless_symbol (x)) + { + if (! cris_pic_sympart_only) + fprintf (file, "$%s+", reg_names [PIC_OFFSET_TABLE_REGNUM]); + assemble_name (file, str); + fprintf (file, ":GOTOFF"); + } + else if (cris_got_symbol (x)) + { + if (cris_pic_sympart_only) + abort (); + fprintf (file, "[$%s+", reg_names [PIC_OFFSET_TABLE_REGNUM]); + assemble_name (file, XSTR (x, 0)); - if (flag_pic == 1) - fprintf (file, ":GOT16]"); - else - fprintf (file, ":GOT]"); - } + if (flag_pic == 1) + fprintf (file, ":GOT16]"); else - LOSE_AND_RETURN ("unexpected PIC symbol", x); - - /* Sanity check. */ - if (! current_function_uses_pic_offset_table) - output_operand_lossage ("PIC register isn't set up"); + fprintf (file, ":GOT]"); } else - assemble_name (file, XSTR (x, 0)); - break; + LOSE_AND_RETURN ("unexpected PIC symbol", x); - case LABEL_REF: - /* If we get one of those here, it should be dressed as PIC. Branch - labels are normally output with the 'l' specifier, which means it - will go directly to output_asm_label and not end up here. */ - if (GET_CODE (XEXP (x, 0)) != CODE_LABEL - && (GET_CODE (XEXP (x, 0)) != NOTE - || NOTE_LINE_NUMBER (XEXP (x, 0)) != NOTE_INSN_DELETED_LABEL)) - fatal_insn ("unexpected address expression", x); + /* Sanity check. */ + if (! current_function_uses_pic_offset_table) + output_operand_lossage ("PIC register isn't set up"); + } + else + assemble_name (file, XSTR (x, 0)); +} - if (flag_pic) - { - if (cris_gotless_symbol (x)) - { - if (! cris_pic_sympart_only) - fprintf (file, "$%s+", reg_names [PIC_OFFSET_TABLE_REGNUM]); - cris_output_addr_const (file, XEXP (x, 0)); +/* Worker function for ASM_OUTPUT_LABEL_REF. */ - fprintf (file, ":GOTOFF"); - } - else - /* Labels are never marked as global symbols. */ - fatal_insn ("unexpected PIC symbol", x); +void +cris_asm_output_label_ref (FILE *file, char *buf) +{ + if (flag_pic && in_code > 0) + { + if (! cris_pic_sympart_only) + fprintf (file, "$%s+", reg_names [PIC_OFFSET_TABLE_REGNUM]); + assemble_name (file, buf); - /* Sanity check. */ - if (! current_function_uses_pic_offset_table) - internal_error ("emitting PIC operand, but PIC register isn't set up"); - break; - } + fprintf (file, ":GOTOFF"); - output_addr_const (file, x); - break; + /* Sanity check. */ + if (! current_function_uses_pic_offset_table) + internal_error ("emitting PIC operand, but PIC register isn't set up"); + } + else + assemble_name (file, buf); +} - case NOTE: - if (NOTE_LINE_NUMBER (x) != NOTE_INSN_DELETED_LABEL) - fatal_insn ("unexpected NOTE as addr_const:", x); - case CODE_LABEL: - case CONST_INT: - case CONST_DOUBLE: - case ZERO_EXTEND: - case SIGN_EXTEND: - output_addr_const (file, x); - break; +/* Worker function for OUTPUT_ADDR_CONST_EXTRA. */ - case CONST: - /* This used to output parentheses around the expression, - but that does not work on the 386 (either ATT or BSD assembler). */ - cris_output_addr_const (file, XEXP (x, 0)); - break; +bool +cris_output_addr_const_extra (FILE *file, rtx x) +{ + switch (GET_CODE (x)) + { + const char *origstr; + const char *str; - case PLUS: - /* Some assemblers need integer constants to appear last (e.g. masm). */ - if (GET_CODE (XEXP (x, 0)) == CONST_INT) + case UNSPEC: + ASSERT_PLT_UNSPEC (x); + x = XVECEXP (x, 0, 0); + origstr = XSTR (x, 0); + str = (* targetm.strip_name_encoding) (origstr); + if (cris_pic_sympart_only) { - cris_output_addr_const (file, XEXP (x, 1)); - if (INTVAL (XEXP (x, 0)) >= 0) - fprintf (file, "+"); - output_addr_const (file, XEXP (x, 0)); + assemble_name (file, str); + fprintf (file, ":PLTG"); } else { - cris_output_addr_const (file, XEXP (x, 0)); - if (GET_CODE (XEXP (x, 1)) != CONST_INT - || INTVAL (XEXP (x, 1)) >= 0) - fprintf (file, "+"); - cris_output_addr_const (file, XEXP (x, 1)); - } - break; + if (TARGET_AVOID_GOTPLT) + /* We shouldn't get here. */ + abort (); - case MINUS: - /* Avoid outputting things like x-x or x+5-x, - since some assemblers can't handle that. */ - x = simplify_subtraction (x); - if (GET_CODE (x) != MINUS) - goto restart; - - cris_output_addr_const (file, XEXP (x, 0)); - fprintf (file, "-"); - if ((GET_CODE (XEXP (x, 1)) == CONST_INT - && INTVAL (XEXP (x, 1)) < 0) - || GET_CODE (XEXP (x, 1)) != CONST_INT) - { - fprintf (file, "%s", targetm.asm_out.open_paren); - cris_output_addr_const (file, XEXP (x, 1)); - fprintf (file, "%s", targetm.asm_out.close_paren); + fprintf (file, "[$%s+", reg_names [PIC_OFFSET_TABLE_REGNUM]); + assemble_name (file, XSTR (x, 0)); + + if (flag_pic == 1) + fprintf (file, ":GOTPLT16]"); + else + fprintf (file, ":GOTPLT]"); } - else - output_addr_const (file, XEXP (x, 1)); - break; + return true; default: - LOSE_AND_RETURN ("unexpected address expression", x); + return false; } } diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index 95cefc7..c0435f7 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -1352,6 +1352,9 @@ struct cum_args {int regs;}; /* Node: Data Output */ +#define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \ + do { if (!cris_output_addr_const_extra (STREAM, X)) goto FAIL; } while (0) + #define IS_ASM_LOGICAL_LINE_SEPARATOR(C) (C) == '@' /* Node: Uninitialized Data */ @@ -1422,6 +1425,12 @@ struct cum_args {int regs;}; #define SUPPORTS_WEAK 1 +#define ASM_OUTPUT_SYMBOL_REF(STREAM, SYM) \ + cris_asm_output_symbol_ref (STREAM, SYM) + +#define ASM_OUTPUT_LABEL_REF(STREAM, BUF) \ + cris_asm_output_label_ref (STREAM, BUF) + /* Remove any previous definition (elfos.h). */ #undef ASM_GENERATE_INTERNAL_LABEL #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ |