diff options
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-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 |
4 files changed, 122 insertions, 146 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2ae5b22..13f8d9a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2005-02-08 Hans-Peter Nilsson <hp@axis.com> + + 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. + 2005-02-08 Paolo Bonzini <bonzini@gnu.org> PR preprocessor/19801 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) \ |