public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, rs6000] Add non-relative jump table support on Power Linux
@ 2020-08-14  7:31 HAO CHEN GUI
  2020-08-20  0:14 ` Segher Boessenkool
  0 siblings, 1 reply; 13+ messages in thread
From: HAO CHEN GUI @ 2020-08-14  7:31 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, wschmidt

[-- Attachment #1: Type: text/plain, Size: 518 bytes --]

Hi,

This patch adds non-relative jump table support on Power Linux. It 
implements ASM_OUTPUT_ADDR_VEC_ELT and adds four new expansions for 
non-relative jump table in rs6000.md. It also defines a rs6000 
option(mrelative-jumptables). If it's set to false, the non-relative 
jump table is picked up even PIC flag is set.

The attachments are the patch diff file and change log file.

Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.  
Is this okay for trunk? Any recommendations? Thanks a lot.


[-- Attachment #2: ChangeLog-1 --]
[-- Type: text/plain, Size: 781 bytes --]

        * config/rs6000/linux64.h (JUMP_TABLES_IN_TEXT_SECTION, JUMP_TABLES_IN_RELRO): Define.
		* config/rs6000/rs6000-protos.h (rs6000_output_addr_vec_elt): Declare.
        * config/rs6000/rs6000.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC, 
		rs6000_gen_pic_addr_diff_vec, rs6000_output_addr_vec_elt): 
		TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC define.
		rs6000_gen_pic_addr_diff_vec, rs6000_output_addr_vec_elt implement.
		* config/rs6000/rs6000.h (rs6000_relative_jumptables, CASE_VECTOR_PC_RELATIVE, 
		CASE_VECTOR_MODE): Define.
		* config/rs6000/rs6000.md (nonrelative_tablejumpsi, nonrelative_tablejumpsi_nospec, 
		nonrelative_tablejumpdi, nonrelative_tablejumpdi_nospec): Add four new expansions.
		* config/rs6000/rs6000.opt (mrelative-jumptables): A new option.

[-- Attachment #3: patch-1.diff --]
[-- Type: text/plain, Size: 10184 bytes --]

diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 34776c8421e..626f2201d96 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -324,7 +324,10 @@ extern int dot_symbols;
 
 /* Indicate that jump tables go in the text section.  */
 #undef  JUMP_TABLES_IN_TEXT_SECTION
-#define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT
+#define JUMP_TABLES_IN_TEXT_SECTION rs6000_relative_jumptables
+
+#undef JUMP_TABLES_IN_RELRO
+#define JUMP_TABLES_IN_RELRO !rs6000_relative_jumptables
 
 /* The linux ppc64 ABI isn't explicit on whether aggregates smaller
    than a doubleword should be padded upward or downward.  You could
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 5508484ba19..820943cdde0 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -155,6 +155,8 @@ extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool);
 extern bool rs6000_pcrel_p (struct function *);
 extern bool rs6000_fndecl_pcrel_p (const_tree);
 
+extern void rs6000_output_addr_vec_elt(FILE *, int);
+
 /* Different PowerPC instruction formats that are used by GCC.  There are
    various other instruction formats used by the PowerPC hardware, but these
    formats are not currently used by GCC.  */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 58f5d780603..0a149e3e99c 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1369,6 +1369,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
 
+#undef  TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC
+#define TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC rs6000_gen_pic_addr_diff_vec
+
 #undef TARGET_LEGITIMIZE_ADDRESS
 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
 
@@ -26494,6 +26497,26 @@ rs6000_cannot_substitute_mem_equiv_p (rtx mem)
   return false;
 }
 
+/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC. Return true if rs6000_relative_jumptables is set. */
+
+static bool
+rs6000_gen_pic_addr_diff_vec (void)
+{
+  return rs6000_relative_jumptables;
+}
+
+void
+rs6000_output_addr_vec_elt (FILE *file, int value)
+{
+  const char *directive = TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t";
+  char buf[100];
+
+  fprintf(file, "%s", directive);
+  ASM_GENERATE_INTERNAL_LABEL (buf, "L", value);
+  assemble_name (file, buf);
+  fprintf(file, "\n");
+}
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-rs6000.h"
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 1209a33173e..9254911836d 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1752,15 +1752,25 @@ typedef struct rs6000_args
 
 /* #define LEGITIMATE_PIC_OPERAND_P (X) */
 \f
-/* Specify the machine mode that this machine uses
-   for the index in the tablejump instruction.  */
-#define CASE_VECTOR_MODE SImode
+
+/* Enable non-relative jump tables for linux ELF. */
+#ifdef TARGET_ELF
+#if !TARGET_AIX 
+#undef rs6000_relative_jumptables
+#define rs6000_relative_jumptables 0
+#endif
+#endif
 
 /* Define as C expression which evaluates to nonzero if the tablejump
    instruction expects the table to contain offsets from the address of the
    table.
    Do not define this if the table should contain absolute addresses.  */
-#define CASE_VECTOR_PC_RELATIVE 1
+#define CASE_VECTOR_PC_RELATIVE 0
+
+/* Specify the machine mode that this machine uses
+   for the index in the tablejump instruction.  */
+#define CASE_VECTOR_MODE \
+  (TARGET_32BIT || rs6000_relative_jumptables ? SImode : DImode)
 
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 0
@@ -2190,6 +2200,11 @@ extern char rs6000_reg_names[][8];	/* register names (0 vs. %r0).  */
        putc ('\n', FILE);				\
      } while (0)
 
+/* This is how to output an element of a case-vector 
+   that is non-relative. */
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+  rs6000_output_addr_vec_elt((FILE), (VALUE))
+
 /* 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/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 0aa5265d199..2f28da0ea1f 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -12669,18 +12669,32 @@
   if (rs6000_speculate_indirect_jumps)
     {
       if (TARGET_32BIT)
-      	emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
-      else
+        {
+          if (rs6000_relative_jumptables)
+            emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
+          else
+      	    emit_jump_insn (gen_nonrelative_tablejumpsi (operands[0], operands[1]));
+        }
+      else if (rs6000_relative_jumptables)
 	emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
+      else 
+        emit_jump_insn (gen_nonrelative_tablejumpdi (operands[0], operands[1]));
     }
   else
     {
       rtx ccreg = gen_reg_rtx (CCmode);
       rtx jump;
       if (TARGET_32BIT)
-	jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
-      else
+        {
+          if (rs6000_relative_jumptables)
+	    jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
+          else
+            jump = gen_nonrelative_tablejumpsi_nospec (operands[0], operands[1], ccreg);
+        }
+      else if (rs6000_relative_jumptables)
 	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+      else
+	jump = gen_nonrelative_tablejumpdi_nospec (operands[0], operands[1], ccreg);
       emit_jump_insn (jump);
     }
   DONE;
@@ -12693,13 +12707,24 @@
    (parallel [(set (pc)
 		   (match_dup 3))
 	      (use (label_ref (match_operand 1)))])]
-  "TARGET_32BIT && rs6000_speculate_indirect_jumps"
+  "TARGET_32BIT && rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
 {
   operands[0] = force_reg (SImode, operands[0]);
   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
   operands[3] = gen_reg_rtx (SImode);
 })
 
+(define_expand "nonrelative_tablejumpsi"
+  [(set (match_dup 2)
+        (match_operand:SI 0 "gpc_reg_operand" "r"))
+   (parallel [(set (pc)
+                   (match_dup 2))
+              (use (label_ref (match_operand 1)))])]
+   "TARGET_32BIT && rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+ {
+  operands[2] = gen_reg_rtx (SImode);
+ })
+
 (define_expand "tablejumpsi_nospec"
   [(set (match_dup 4)
 	(plus:SI (match_operand:SI 0)
@@ -12708,13 +12733,25 @@
 		   (match_dup 4))
 	      (use (label_ref (match_operand 1)))
 	      (clobber (match_operand 2))])]
-  "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
+  "TARGET_32BIT && !rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
 {
   operands[0] = force_reg (SImode, operands[0]);
   operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
   operands[4] = gen_reg_rtx (SImode);
 })
 
+(define_expand "nonrelative_tablejumpsi_nospec"
+  [(set (match_dup 3)
+        (match_operand:SI 0 "gpc_reg_operand" "r"))
+   (parallel [(set (pc)
+                   (match_dup 3))
+              (use (label_ref (match_operand 1)))
+              (clobber (match_operand 2))])]
+  "TARGET_32BIT && !rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+{
+  operands[3] = gen_reg_rtx (SImode);
+})
+
 (define_expand "tablejumpdi"
   [(set (match_dup 4)
         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
@@ -12724,13 +12761,24 @@
    (parallel [(set (pc)
 		   (match_dup 3))
 	      (use (label_ref (match_operand 1)))])]
-  "TARGET_64BIT && rs6000_speculate_indirect_jumps"
+  "TARGET_64BIT && rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
 {
   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
   operands[3] = gen_reg_rtx (DImode);
   operands[4] = gen_reg_rtx (DImode);
 })
 
+(define_expand "nonrelative_tablejumpdi"
+  [(set (match_dup 2)
+        (match_operand:DI 0 "gpc_reg_operand" "r"))
+   (parallel [(set (pc)
+                   (match_dup 2))
+              (use (label_ref (match_operand 1)))])]
+   "TARGET_64BIT && rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+ {
+  operands[2] = gen_reg_rtx (DImode);
+ })
+
 (define_expand "tablejumpdi_nospec"
   [(set (match_dup 5)
         (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
@@ -12741,13 +12789,25 @@
 		   (match_dup 4))
 	      (use (label_ref (match_operand 1)))
 	      (clobber (match_operand 2))])]
-  "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
+  "TARGET_64BIT && !rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
 {
   operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
   operands[4] = gen_reg_rtx (DImode);
   operands[5] = gen_reg_rtx (DImode);
 })
 
+(define_expand "nonrelative_tablejumpdi_nospec"
+  [(set (match_dup 3)
+        (match_operand:DI 0 "gpc_reg_operand" "r"))
+   (parallel [(set (pc)
+                   (match_dup 3))
+              (use (label_ref (match_operand 1)))
+              (clobber (match_operand 2))])]
+  "TARGET_64BIT && !rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+{
+  operands[3] = gen_reg_rtx (DImode);
+})
+
 (define_insn "*tablejump<mode>_internal1"
   [(set (pc)
 	(match_operand:P 0 "register_operand" "c,*l"))
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index f95b8279270..7cf8bdb1faa 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -578,3 +578,6 @@ Generate (do not generate) prefixed memory instructions.
 mpcrel
 Target Report Mask(PCREL) Var(rs6000_isa_flags)
 Generate (do not generate) pc-relative memory addressing.
+
+mrelative-jumptables
+Target Undocumented Var(rs6000_relative_jumptables) Init(1) Save

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2020-11-27  1:16 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-14  7:31 [PATCH, rs6000] Add non-relative jump table support on Power Linux HAO CHEN GUI
2020-08-20  0:14 ` Segher Boessenkool
2020-08-24  7:48   ` HAO CHEN GUI
2020-09-07 21:46     ` Segher Boessenkool
2020-09-09  8:55       ` HAO CHEN GUI
2020-09-28  0:37         ` HAO CHEN GUI
2020-09-28 22:46         ` Segher Boessenkool
2020-10-15  8:46           ` HAO CHEN GUI
2020-11-06  1:02             ` HAO CHEN GUI
2020-11-16  6:56               ` HAO CHEN GUI
2020-11-23  2:41               ` HAO CHEN GUI
2020-11-23 22:25             ` Segher Boessenkool
2020-11-27  1:16               ` HAO CHEN GUI

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).