aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <danglin@gcc.gnu.org>2014-08-16 16:36:33 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2014-08-16 16:36:33 +0000
commit3ba07ad32081301b3e23716802ec26ba352dd5ac (patch)
tree232ae71258f3c9abc3172d69fabb376e0e1544a9
parent5f05dc5550287bc09490f7aeeffbdad80288b5e5 (diff)
downloadgcc-3ba07ad32081301b3e23716802ec26ba352dd5ac.zip
gcc-3ba07ad32081301b3e23716802ec26ba352dd5ac.tar.gz
gcc-3ba07ad32081301b3e23716802ec26ba352dd5ac.tar.bz2
re PR target/61641 (undefined label in jump_table_data)
PR target/61641 * config/pa/pa-protos.h (pa_output_addr_vec, pa_output_addr_diff_vec): Declare. * config/pa/pa.c (pa_reorg): Remove code to insert brtab marker insns. (pa_output_addr_vec, pa_output_addr_diff_vec): New. * config/pa/pa.h (ASM_OUTPUT_ADDR_VEC, ASM_OUTPUT_ADDR_DIFF_VEC): Define. * config/pa/pa.md (begin_brtab): Delete insn. (end_brtab): Likewise. From-SVN: r214064
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/pa/pa-protos.h2
-rw-r--r--gcc/config/pa/pa.c69
-rw-r--r--gcc/config/pa/pa.h10
-rw-r--r--gcc/config/pa/pa.md30
5 files changed, 67 insertions, 56 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0d7dd91..081bd12 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2014-08-16 John David Anglin <danglin@gcc.gnu.org>
+
+ PR target/61641
+ * config/pa/pa-protos.h (pa_output_addr_vec, pa_output_addr_diff_vec):
+ Declare.
+ * config/pa/pa.c (pa_reorg): Remove code to insert brtab marker insns.
+ (pa_output_addr_vec, pa_output_addr_diff_vec): New.
+ * config/pa/pa.h (ASM_OUTPUT_ADDR_VEC, ASM_OUTPUT_ADDR_DIFF_VEC):
+ Define.
+ * config/pa/pa.md (begin_brtab): Delete insn.
+ (end_brtab): Likewise.
+
2014-08-16 Manuel López-Ibáñez <manu@gcc.gnu.org>
* doc/cppopts.texi (ftrack-macro-expansion): Add missing @code.
diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h
index e72abea..45031e2 100644
--- a/gcc/config/pa/pa-protos.h
+++ b/gcc/config/pa/pa-protos.h
@@ -49,6 +49,8 @@ extern const char *pa_output_mul_insn (int, rtx);
extern const char *pa_output_div_insn (rtx *, int, rtx);
extern const char *pa_output_mod_insn (int, rtx);
extern const char *pa_singlemove_string (rtx *);
+extern void pa_output_addr_vec (rtx, rtx);
+extern void pa_output_addr_diff_vec (rtx, rtx);
extern void pa_output_arg_descriptor (rtx);
extern void pa_output_global_address (FILE *, rtx, int);
extern void pa_print_operand (FILE *, rtx, int);
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index d52d52f..d47d5c8 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -8926,40 +8926,15 @@ pa_following_call (rtx insn)
}
/* We use this hook to perform a PA specific optimization which is difficult
- to do in earlier passes.
-
- We surround the jump table itself with BEGIN_BRTAB and END_BRTAB
- insns. Those insns mark where we should emit .begin_brtab and
- .end_brtab directives when using GAS. This allows for better link
- time optimizations. */
+ to do in earlier passes. */
static void
pa_reorg (void)
{
- rtx insn;
-
remove_useless_addtr_insns (1);
if (pa_cpu < PROCESSOR_8000)
pa_combine_instructions ();
-
- /* Still need brtab marker insns. FIXME: the presence of these
- markers disables output of the branch table to readonly memory,
- and any alignment directives that might be needed. Possibly,
- the begin_brtab insn should be output before the label for the
- table. This doesn't matter at the moment since the tables are
- always output in the text section. */
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
- /* Find an ADDR_VEC insn. */
- if (! JUMP_TABLE_DATA_P (insn))
- continue;
-
- /* Now generate markers for the beginning and end of the
- branch table. */
- emit_insn_before (gen_begin_brtab (), insn);
- emit_insn_after (gen_end_brtab (), insn);
- }
}
/* The PA has a number of odd instructions which can perform multiple
@@ -10554,4 +10529,46 @@ pa_legitimize_reload_address (rtx ad, enum machine_mode mode,
return NULL_RTX;
}
+/* Output address vector. */
+
+void
+pa_output_addr_vec (rtx lab, rtx body)
+{
+ int idx, vlen = XVECLEN (body, 0);
+
+ targetm.asm_out.internal_label (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
+ if (TARGET_GAS)
+ fputs ("\t.begin_brtab\n", asm_out_file);
+ for (idx = 0; idx < vlen; idx++)
+ {
+ ASM_OUTPUT_ADDR_VEC_ELT
+ (asm_out_file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
+ }
+ if (TARGET_GAS)
+ fputs ("\t.end_brtab\n", asm_out_file);
+}
+
+/* Output address difference vector. */
+
+void
+pa_output_addr_diff_vec (rtx lab, rtx body)
+{
+ rtx base = XEXP (XEXP (body, 0), 0);
+ int idx, vlen = XVECLEN (body, 1);
+
+ targetm.asm_out.internal_label (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
+ if (TARGET_GAS)
+ fputs ("\t.begin_brtab\n", asm_out_file);
+ for (idx = 0; idx < vlen; idx++)
+ {
+ ASM_OUTPUT_ADDR_DIFF_ELT
+ (asm_out_file,
+ body,
+ CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
+ CODE_LABEL_NUMBER (base));
+ }
+ if (TARGET_GAS)
+ fputs ("\t.end_brtab\n", asm_out_file);
+}
+
#include "gt-pa.h"
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 7292d6a..9a1773f 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -1193,6 +1193,16 @@ do { \
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
fprintf (FILE, "\t.word L$%04d-L$%04d\n", VALUE, REL)
+/* This is how to output an absolute case-vector. */
+
+#define ASM_OUTPUT_ADDR_VEC(LAB,BODY) \
+ pa_output_addr_vec ((LAB),(BODY))
+
+/* This is how to output a relative case-vector. */
+
+#define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,BODY) \
+ pa_output_addr_diff_vec ((LAB),(BODY))
+
/* This is how to output an assembler line that says to advance the
location counter to a multiple of 2**LOG bytes. */
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index e55d0b8..a9421ac 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -8508,36 +8508,6 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
[(set_attr "type" "move")
(set_attr "length" "4")])
-;; These are just placeholders so we know where branch tables
-;; begin and end.
-(define_insn "begin_brtab"
- [(const_int 1)]
- ""
- "*
-{
- /* Only GAS actually supports this pseudo-op. */
- if (TARGET_GAS)
- return \".begin_brtab\";
- else
- return \"\";
-}"
- [(set_attr "type" "move")
- (set_attr "length" "0")])
-
-(define_insn "end_brtab"
- [(const_int 2)]
- ""
- "*
-{
- /* Only GAS actually supports this pseudo-op. */
- if (TARGET_GAS)
- return \".end_brtab\";
- else
- return \"\";
-}"
- [(set_attr "type" "move")
- (set_attr "length" "0")])
-
;;; EH does longjmp's from and within the data section. Thus,
;;; an interspace branch is required for the longjmp implementation.
;;; Registers r1 and r2 are used as scratch registers for the jump