diff mbox

[committed] Use ASM_OUTPUT_ADDR_VEC and ASM_OUTPUT_ADDR_DIFF_VEC to output branch tables

Message ID BLU436-SMTP171A1E5BE9A5AC1BE969BDB97D60@phx.gbl
State New
Headers show

Commit Message

John David Anglin Aug. 16, 2014, 5:13 p.m. UTC
This patch fixes a regression introduced in 4.9 in reworking the  
handling of branch tables.  The branch
table markers inserted by pa_reorg prevent the removal of jump tables  
in the delayed branch pass.  This
results in the branch table being left in the instruction stream when  
it should have been removed and
an assembly error.

This patch removes the markers from the RTL stream, and uses  
ASM_OUTPUT_ADDR_VEC and
ASM_OUTPUT_ADDR_DIFF_VEC to output the branch tables.  This is more  
efficient and the RTL
no longer has marker insns between the branch table label and the  
branch table.

Tested on hppa-unknown-linux-gnu, hppa2.0w-hp-hpux11.11 and hppa64-hp- 
hpux11.11.  Committed
to trunk and 4.9.

Dave
--
John David Anglin	dave.anglin@bell.net
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.
diff mbox

Patch

Index: config/pa/pa-protos.h
===================================================================
--- config/pa/pa-protos.h	(revision 213778)
+++ config/pa/pa-protos.h	(working copy)
@@ -49,6 +49,8 @@ 
 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);
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c	(revision 213778)
+++ config/pa/pa.c	(working copy)
@@ -8926,40 +8928,15 @@ 
 }
 
 /* We use this hook to perform a PA specific optimization which is difficult
-   to do in earlier passes.
+   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.  */
-
 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 +10531,46 @@ 
   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"
Index: config/pa/pa.h
===================================================================
--- config/pa/pa.h	(revision 213778)
+++ config/pa/pa.h	(working copy)
@@ -1193,6 +1193,16 @@ 
 #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.  */
 
Index: config/pa/pa.md
===================================================================
--- config/pa/pa.md	(revision 213778)
+++ config/pa/pa.md	(working copy)
@@ -8508,36 +8508,6 @@ 
   [(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