+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.
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);
}
/* 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
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"
#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. */
[(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