aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/cfglayout.c6
-rw-r--r--gcc/final.c20
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/20050321-2.c54
5 files changed, 88 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a308f21..f5e1820 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2005-03-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/20561
+ * cfglayout.c (reemit_insn_block_notes): Don't put block notes in
+ between jump table and its label.
+ * final.c (shorten_branches): Handle notes in between ADDR_VEC
+ resp. ADDR_DIFF_VEC and the label preceeding it.
+ (final_scan_insn): Likewise. Ensure ADDR_VEC resp. ADDR_DIFF_VEC
+ is emitted in the right section.
+
2005-03-22 Kazu Hirata <kazu@cs.umass.edu>
* fold-const.c (fold_unary, fold_binary): Update comments
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index 981bcd9..655c9a1 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -523,6 +523,12 @@ reemit_insn_block_notes (void)
{
tree this_block;
+ /* Avoid putting scope notes between jump table and its label. */
+ if (JUMP_P (insn)
+ && (GET_CODE (PATTERN (insn)) == ADDR_VEC
+ || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
+ continue;
+
this_block = insn_scope (insn);
/* For sequences compute scope resulting from merging all scopes
of instructions nested inside. */
diff --git a/gcc/final.c b/gcc/final.c
index bf5771a..9347efe 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -835,7 +835,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
max_log = log;
max_skip = LABEL_ALIGN_MAX_SKIP;
}
- next = NEXT_INSN (insn);
+ next = next_nonnote_insn (insn);
/* ADDR_VECs only take room if read-only data goes into the text
section. */
if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION)
@@ -1677,6 +1677,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
#ifdef HAVE_cc0
rtx set;
#endif
+ rtx next;
insn_counter++;
@@ -1932,10 +1933,11 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
fputs (ASM_APP_OFF, file);
app_on = 0;
}
- if (NEXT_INSN (insn) != 0
- && JUMP_P (NEXT_INSN (insn)))
+
+ next = next_nonnote_insn (insn);
+ if (next != 0 && JUMP_P (next))
{
- rtx nextbody = PATTERN (NEXT_INSN (insn));
+ rtx nextbody = PATTERN (next);
/* If this label is followed by a jump-table,
make sure we put the label in the read-only section. Also
@@ -1956,7 +1958,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
targetm.asm_out.function_rodata_section (current_function_decl);
#ifdef ADDR_VEC_ALIGN
- log_align = ADDR_VEC_ALIGN (NEXT_INSN (insn));
+ log_align = ADDR_VEC_ALIGN (next);
#else
log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
#endif
@@ -1967,7 +1969,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
#ifdef ASM_OUTPUT_CASE_LABEL
ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
- NEXT_INSN (insn));
+ next);
#else
targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
#endif
@@ -2022,6 +2024,11 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
if (prescan > 0)
break;
+ if (! JUMP_TABLES_IN_TEXT_SECTION)
+ targetm.asm_out.function_rodata_section (current_function_decl);
+ else
+ function_section (current_function_decl);
+
if (app_on)
{
fputs (ASM_APP_OFF, file);
@@ -2157,7 +2164,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
{
/* A delayed-branch sequence */
int i;
- rtx next;
if (prescan > 0)
break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e7222ef..8960528 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-03-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/20561
+ * gcc.dg/20050321-2.c: New test.
+
2005-03-22 Nathan Sidwell <nathan@codesourcery.com>
PR c++/20465
diff --git a/gcc/testsuite/gcc.dg/20050321-2.c b/gcc/testsuite/gcc.dg/20050321-2.c
new file mode 100644
index 0000000..ac31914
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20050321-2.c
@@ -0,0 +1,54 @@
+/* This testcase could not assemble on ppc32, because the compiler assumed
+ the huge ADDR_DIFF_VEC will be emitted into rodata section, yet because
+ of some notes inserted between jump table's CODE_LABEL and the jump table
+ it ended up in the .text section and thus shorten_branches couldn't
+ figure out branch to lab is too far. */
+/* { dg-do link } */
+/* { dg-options "-g1 -fpic" } */
+
+#define A(n) \
+ case n##1: return n##1 * 131 + 63; \
+ case n##3: return n##3 * 1231 + 182; \
+ case n##5: return n##5 * 351 + 1; \
+ case n##7: return n##7 * 312 + 61; \
+ case n##9: return n##9 * 17 - 1;
+#define B(n) \
+A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) \
+A(n##5) A(n##6) A(n##7) A(n##8) A(n##9)
+#define C(n) \
+B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) \
+B(n##5) B(n##6) B(n##7) B(n##8) B(n##9)
+#define D(n) \
+C(n##0) C(n##1) B(n##20) B(n##21) B(n##22)
+
+int
+foo (int x)
+{
+ {
+lab:;
+ int a = x;
+ while (a < 60000)
+ {
+ int b = a;
+ {
+ int c = b;
+ switch (c)
+ {
+ D(1)
+ default: break;
+ }
+ }
+ a += 10000;
+ if (a == 4168)
+ goto lab;
+ }
+ }
+ return x;
+}
+
+int
+main (void)
+{
+ foo (71);
+ return 0;
+}