aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/cris
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2005-02-08 15:35:12 +0000
committerHans-Peter Nilsson <hp@gcc.gnu.org>2005-02-08 15:35:12 +0000
commit453bd0f554e8afa38eab4b4f3dffd3ec1a647c09 (patch)
tree67f378a8e25e7f88e70640fb844197d14630e5c7 /gcc/config/cris
parent749c6ef9922642ee4f01a263f3803b3dcf8d850d (diff)
downloadgcc-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.h4
-rw-r--r--gcc/config/cris/cris.c238
-rw-r--r--gcc/config/cris/cris.h9
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) \