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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  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
  0 siblings, 1 reply; 13+ messages in thread
From: Segher Boessenkool @ 2020-08-20  0:14 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: gcc-patches, wschmidt

Hi!

Sorry this took so long to review.  "I lost track of this patch", what
can I say :-/

On Fri, Aug 14, 2020 at 03:31:05PM +0800, HAO CHEN GUI wrote:
> 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.

> 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 third choice is .rodata.  .data.rel.ro can be considered to be a
sub-case of that, but not the other way around.

> +extern void rs6000_output_addr_vec_elt(FILE *, int);

(space before opening paren)

> +/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC. Return true if rs6000_relative_jumptables is set. */

The maximum line length is 80 characters.  Two spaces after a full stop.

> +/* 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

AIX never is ELF, but many other things *are* ELF.  Do all of those
handle .data.rel.ro, including do they have enough OS support for it?

This also changes the default for ELF systems?  Let's not do that (in
this patch, that is).

> +/* 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 CASE_VECTOR_MODE (rs6000_relative_jumptables ? SImode : Pmode)

> +/* This is how to output an element of a case-vector 
> +   that is non-relative. */

(no space at end of line; two spaces after full stop, also before */)

> +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
> +  rs6000_output_addr_vec_elt((FILE), (VALUE))

Space before first ( please (on the second line, on the first you
cannot -- macro definitions are the only exception).

> 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]));

Please fix the indent while you're at it (tabs shouldn't follow spaces).
Oh, and line too long.

> +        }
> +      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]));

Please put the "relative" case on the outside, and the "32 or 64" if on
the inside.

> +(define_expand "nonrelative_tablejumpsi"

Maybe call it "absolute_tablejumpsi"?  Not sure :-)

> +   "TARGET_32BIT && rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"

Line too long (more follow, I won't point all out, please check :-) )

> + {
> +  operands[2] = gen_reg_rtx (SImode);
> + })

No spaces before { and } here, those are flush left like in outer braces
in a C function are.

> +(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))])]

Please use a leading tab instead of every 8 leading spaces.


I'll try to be quicker at reviewing iterations of this -- there is quite
some way to go, without me slowing things down!


Segher

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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  2020-08-20  0:14 ` Segher Boessenkool
@ 2020-08-24  7:48   ` HAO CHEN GUI
  2020-09-07 21:46     ` Segher Boessenkool
  0 siblings, 1 reply; 13+ messages in thread
From: HAO CHEN GUI @ 2020-08-24  7:48 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, wschmidt

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

Hi,

I revised the patch according to the advice. The attachment is the 
change log and diff file. Thanks a lot.

On 20/8/2020 上午 8:14, Segher Boessenkool wrote:
> Hi!
>
> Sorry this took so long to review.  "I lost track of this patch", what
> can I say :-/
>
> On Fri, Aug 14, 2020 at 03:31:05PM +0800, HAO CHEN GUI wrote:
>> 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.
>> 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 third choice is .rodata.  .data.rel.ro can be considered to be a
> sub-case of that, but not the other way around.
>
>> +extern void rs6000_output_addr_vec_elt(FILE *, int);
> (space before opening paren)
>
>> +/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC. Return true if rs6000_relative_jumptables is set. */
> The maximum line length is 80 characters.  Two spaces after a full stop.
>
>> +/* 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
> AIX never is ELF, but many other things *are* ELF.  Do all of those
> handle .data.rel.ro, including do they have enough OS support for it?
>
> This also changes the default for ELF systems?  Let's not do that (in
> this patch, that is).
>
>> +/* 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 CASE_VECTOR_MODE (rs6000_relative_jumptables ? SImode : Pmode)
>
>> +/* This is how to output an element of a case-vector
>> +   that is non-relative. */
> (no space at end of line; two spaces after full stop, also before */)
>
>> +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
>> +  rs6000_output_addr_vec_elt((FILE), (VALUE))
> Space before first ( please (on the second line, on the first you
> cannot -- macro definitions are the only exception).
>
>> 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]));
> Please fix the indent while you're at it (tabs shouldn't follow spaces).
> Oh, and line too long.
>
>> +        }
>> +      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]));
> Please put the "relative" case on the outside, and the "32 or 64" if on
> the inside.
>
>> +(define_expand "nonrelative_tablejumpsi"
> Maybe call it "absolute_tablejumpsi"?  Not sure :-)
>
>> +   "TARGET_32BIT && rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
> Line too long (more follow, I won't point all out, please check :-) )
>
>> + {
>> +  operands[2] = gen_reg_rtx (SImode);
>> + })
> No spaces before { and } here, those are flush left like in outer braces
> in a C function are.
>
>> +(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))])]
> Please use a leading tab instead of every 8 leading spaces.
>
>
> I'll try to be quicker at reviewing iterations of this -- there is quite
> some way to go, without me slowing things down!
>
>
> Segher

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

	* config/rs6000/linux.h (rs6000_relative_jumptables): Define.
	* config/rs6000/linux64.h (JUMP_TABLES_IN_TEXT_SECTION,
	rs6000_relative_jumptables): Define.
	* config/rs6000/rs6000-protos.h (rs6000_output_addr_vec_elt): Declare.
	* config/rs6000/rs6000.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC):
	Define
	(rs6000_gen_pic_addr_diff_vec, rs6000_output_addr_vec_elt): Implement.
	* config/rs6000/rs6000.h (CASE_VECTOR_PC_RELATIVE,
	CASE_VECTOR_MODE, ASM_OUTPUT_ADDR_VEC_ELT): Define.
	* config/rs6000/rs6000.md (absolute_tablejumpsi,
	absolute_tablejumpsi_nospec, absolute_tablejumpdi,
	absolute_tablejumpdi_nospec): Add four new expansions.
	* config/rs6000/rs6000.opt (mrelative-jumptables): Add a new option and
	set rs6000_relative_jumptables to true by default.

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

diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
index b7026fcbee7..bd6c3989801 100644
--- a/gcc/config/rs6000/linux.h
+++ b/gcc/config/rs6000/linux.h
@@ -145,3 +145,7 @@
   || (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 19)
 #define RS6000_GLIBC_ATOMIC_FENV 1
 #endif
+
+/* Disable relative jump tables for Power Linux.  */
+#undef rs6000_relative_jumptables
+#define rs6000_relative_jumptables 0
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 34776c8421e..41051459db9 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -322,9 +322,13 @@ extern int dot_symbols;
 #define TARGET_ALIGN_NATURAL 1
 #endif
 
+/* Disable relative jump tables for Power Linux64.  */
+#undef rs6000_relative_jumptables
+#define rs6000_relative_jumptables 0
+
 /* 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
 
 /* 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..62564dd67f2 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..94d1e650b94 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,27 @@ 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..d96d22590d7 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1752,15 +1752,16 @@ 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
-
 /* 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 +2191,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..868609641a6 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -12668,19 +12668,35 @@
 {
   if (rs6000_speculate_indirect_jumps)
     {
-      if (TARGET_32BIT)
-      	emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
+      if (rs6000_relative_jumptables)
+	{
+	  if (TARGET_32BIT)
+	    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
+	  else
+	    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
+	}
+      else if (TARGET_32BIT)
+	emit_jump_insn (gen_absolute_tablejumpsi (operands[0], operands[1]));
       else
-	emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
+	emit_jump_insn (gen_absolute_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);
+      if (rs6000_relative_jumptables)
+	{
+	  if (TARGET_32BIT)
+	    jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
+	  else
+	    jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+	}
+      else if (TARGET_32BIT)
+	jump = gen_absolute_tablejumpsi_nospec (operands[0], operands[1],
+						ccreg);
       else
-	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+	jump = gen_absolute_tablejumpdi_nospec (operands[0], operands[1],
+						ccreg);
       emit_jump_insn (jump);
     }
   DONE;
@@ -12693,13 +12709,26 @@
    (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 "absolute_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,32 +12737,59 @@
 		   (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 "absolute_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")))
+	(sign_extend:DI (match_operand:SI 0 "lwa_operand")))
    (set (match_dup 3)
 	(plus:DI (match_dup 4)
 		 (match_dup 2)))
    (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 "absolute_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")))
+	(sign_extend:DI (match_operand:SI 0 "lwa_operand")))
    (set (match_dup 4)
 	(plus:DI (match_dup 5)
 		 (match_dup 3)))
@@ -12741,13 +12797,27 @@
 		   (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 "absolute_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
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c

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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  2020-08-24  7:48   ` HAO CHEN GUI
@ 2020-09-07 21:46     ` Segher Boessenkool
  2020-09-09  8:55       ` HAO CHEN GUI
  0 siblings, 1 reply; 13+ messages in thread
From: Segher Boessenkool @ 2020-09-07 21:46 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: gcc-patches, wschmidt

On Mon, Aug 24, 2020 at 03:48:43PM +0800, HAO CHEN GUI wrote:
> >I'll try to be quicker at reviewing iterations of this -- there is quite
> >some way to go, without me slowing things down!

Sigh :-(

> 	* config/rs6000/linux.h (rs6000_relative_jumptables): Define.

That macro looks like it is variable (or function).  *Make* it a
variable, please?

> 	* config/rs6000/rs6000.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC):
> 	Define

Period?

> 	(rs6000_gen_pic_addr_diff_vec, rs6000_output_addr_vec_elt): Implement.

"New function."

> 	* config/rs6000/rs6000.md (absolute_tablejumpsi,
> 	absolute_tablejumpsi_nospec, absolute_tablejumpdi,
> 	absolute_tablejumpdi_nospec): Add four new expansions.

"New define_expands." or "New expanders."

> 	* config/rs6000/rs6000.opt (mrelative-jumptables): Add a new option and
> 	set rs6000_relative_jumptables to true by default.

"rs6000.opt: Add -mrelative-jumptables."

> +/* Disable relative jump tables for Power Linux.  */
> +#undef rs6000_relative_jumptables
> +#define rs6000_relative_jumptables 0

Why?

> +/* Disable relative jump tables for Power Linux64.  */
> +#undef rs6000_relative_jumptables
> +#define rs6000_relative_jumptables 0

(That's not what it's called...  Just don't say the "for..." at all?
It is clear from what file it is in.)

>  /* 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

Not sure that is correct.  Maybe the patch using rodata (.data.rel.ro)
should be a separate patch?

>  /* 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

This should depend on the new flag?

> +/* 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)

rs6000_relative_jumptables ? SImode : Pmode;

> +      if (rs6000_relative_jumptables)
> +	{
> +	  if (TARGET_32BIT)
> +	    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
> +	  else
> +	    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
> +	}

Hrm, I guess we should make that a parameterized name (future work,
don't do it now :-) )

> +(define_expand "absolute_tablejumpsi"

Don't prefix names; it should start with "tablejump".


Segher

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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  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
  0 siblings, 2 replies; 13+ messages in thread
From: HAO CHEN GUI @ 2020-09-09  8:55 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, wschmidt

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

Hi Segher,

     Thanks for your advice. I removed macros defined in linux64.h and 
linux.h. So they take relative jump tables by default. When 
no-relative-jumptables is set, the absolute jump tables are taken. All 
things relevant to section relocations are put in another patch. Thanks 
again.


On 8/9/2020 上午 5:46, Segher Boessenkool wrote:
> On Mon, Aug 24, 2020 at 03:48:43PM +0800, HAO CHEN GUI wrote:
>>> I'll try to be quicker at reviewing iterations of this -- there is quite
>>> some way to go, without me slowing things down!
> Sigh :-(
>
>> 	* config/rs6000/linux.h (rs6000_relative_jumptables): Define.
> That macro looks like it is variable (or function).  *Make* it a
> variable, please?
>
>> 	* config/rs6000/rs6000.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC):
>> 	Define
> Period?
>
>> 	(rs6000_gen_pic_addr_diff_vec, rs6000_output_addr_vec_elt): Implement.
> "New function."
>
>> 	* config/rs6000/rs6000.md (absolute_tablejumpsi,
>> 	absolute_tablejumpsi_nospec, absolute_tablejumpdi,
>> 	absolute_tablejumpdi_nospec): Add four new expansions.
> "New define_expands." or "New expanders."
>
>> 	* config/rs6000/rs6000.opt (mrelative-jumptables): Add a new option and
>> 	set rs6000_relative_jumptables to true by default.
> "rs6000.opt: Add -mrelative-jumptables."
>
>> +/* Disable relative jump tables for Power Linux.  */
>> +#undef rs6000_relative_jumptables
>> +#define rs6000_relative_jumptables 0
> Why?
>
>> +/* Disable relative jump tables for Power Linux64.  */
>> +#undef rs6000_relative_jumptables
>> +#define rs6000_relative_jumptables 0
> (That's not what it's called...  Just don't say the "for..." at all?
> It is clear from what file it is in.)
>
>>   /* 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
> Not sure that is correct.  Maybe the patch using rodata (.data.rel.ro)
> should be a separate patch?
>
>>   /* 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
> This should depend on the new flag?
>
>> +/* 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)
> rs6000_relative_jumptables ? SImode : Pmode;
>
>> +      if (rs6000_relative_jumptables)
>> +	{
>> +	  if (TARGET_32BIT)
>> +	    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
>> +	  else
>> +	    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
>> +	}
> Hrm, I guess we should make that a parameterized name (future work,
> don't do it now :-) )
>
>> +(define_expand "absolute_tablejumpsi"
> Don't prefix names; it should start with "tablejump".
>
>
> Segher

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

	* config/rs6000/rs6000-protos.h (rs6000_output_addr_vec_elt): Declare.
	* config/rs6000/rs6000.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC):
	Define.
	(rs6000_gen_pic_addr_diff_vec, rs6000_output_addr_vec_elt): Implement.
	* config/rs6000/rs6000.h (CASE_VECTOR_PC_RELATIVE,
	CASE_VECTOR_MODE, ASM_OUTPUT_ADDR_VEC_ELT): Define.
	* config/rs6000/rs6000.md (tablejumpsi_absolute,
	tablejumpsi_nospec_absolute, tablejumpdi_absolute,
	tablejumpdi_nospec_absolute): New expanders.
	* config/rs6000/rs6000.opt (mrelative-jumptables): Add
	mrelative-jumptables.

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

diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 5508484ba19..62564dd67f2 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..94d1e650b94 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,27 @@ 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..6759ac0de11 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1752,15 +1752,16 @@ 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
-
 /* 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 rs6000_relative_jumptables
+
+/* 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 : Pmode)
 
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 0
@@ -2190,6 +2191,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..7381c4909c3 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -12668,19 +12668,35 @@
 {
   if (rs6000_speculate_indirect_jumps)
     {
-      if (TARGET_32BIT)
-      	emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
+      if (rs6000_relative_jumptables)
+	{
+	  if (TARGET_32BIT)
+	    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
+	  else
+	    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
+	}
+      else if (TARGET_32BIT)
+	emit_jump_insn (gen_tablejumpsi_absolute (operands[0], operands[1]));
       else
-	emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
+	emit_jump_insn (gen_tablejumpdi_absolute (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);
+      if (rs6000_relative_jumptables)
+	{
+	  if (TARGET_32BIT)
+	    jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
+	  else
+	    jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+	}
+      else if (TARGET_32BIT)
+	jump = gen_tablejumpsi_nospec_absolute (operands[0], operands[1],
+						ccreg);
       else
-	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+	jump = gen_tablejumpdi_nospec_absolute (operands[0], operands[1],
+						ccreg);
       emit_jump_insn (jump);
     }
   DONE;
@@ -12693,13 +12709,26 @@
    (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 "tablejumpsi_absolute"
+  [(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,32 +12737,59 @@
 		   (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 "tablejumpsi_nospec_absolute"
+  [(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")))
+	(sign_extend:DI (match_operand:SI 0 "lwa_operand")))
    (set (match_dup 3)
 	(plus:DI (match_dup 4)
 		 (match_dup 2)))
    (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 "tablejumpdi_absolute"
+  [(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")))
+	(sign_extend:DI (match_operand:SI 0 "lwa_operand")))
    (set (match_dup 4)
 	(plus:DI (match_dup 5)
 		 (match_dup 3)))
@@ -12741,13 +12797,27 @@
 		   (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 "tablejumpdi_nospec_absolute"
+  [(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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  2020-09-09  8:55       ` HAO CHEN GUI
@ 2020-09-28  0:37         ` HAO CHEN GUI
  2020-09-28 22:46         ` Segher Boessenkool
  1 sibling, 0 replies; 13+ messages in thread
From: HAO CHEN GUI @ 2020-09-28  0:37 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, wschmidt

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

Segher,

     Gentle ping this:

	https://gcc.gnu.org/pipermail/gcc-patches/2020-September/553486.html
Thanks
Gui Haochen

On 9/9/2020 下午 4:55, HAO CHEN GUI wrote:
> Hi Segher,
>
>     Thanks for your advice. I removed macros defined in linux64.h and 
> linux.h. So they take relative jump tables by default. When 
> no-relative-jumptables is set, the absolute jump tables are taken. All 
> things relevant to section relocations are put in another patch. 
> Thanks again.
>
>
> On 8/9/2020 上午 5:46, Segher Boessenkool wrote:
>> On Mon, Aug 24, 2020 at 03:48:43PM +0800, HAO CHEN GUI wrote:
>>>> I'll try to be quicker at reviewing iterations of this -- there is 
>>>> quite
>>>> some way to go, without me slowing things down!
>> Sigh :-(
>>
>>>     * config/rs6000/linux.h (rs6000_relative_jumptables): Define.
>> That macro looks like it is variable (or function).  *Make* it a
>> variable, please?
>>
>>>     * config/rs6000/rs6000.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC):
>>>     Define
>> Period?
>>
>>>     (rs6000_gen_pic_addr_diff_vec, rs6000_output_addr_vec_elt): 
>>> Implement.
>> "New function."
>>
>>>     * config/rs6000/rs6000.md (absolute_tablejumpsi,
>>>     absolute_tablejumpsi_nospec, absolute_tablejumpdi,
>>>     absolute_tablejumpdi_nospec): Add four new expansions.
>> "New define_expands." or "New expanders."
>>
>>>     * config/rs6000/rs6000.opt (mrelative-jumptables): Add a new 
>>> option and
>>>     set rs6000_relative_jumptables to true by default.
>> "rs6000.opt: Add -mrelative-jumptables."
>>
>>> +/* Disable relative jump tables for Power Linux.  */
>>> +#undef rs6000_relative_jumptables
>>> +#define rs6000_relative_jumptables 0
>> Why?
>>
>>> +/* Disable relative jump tables for Power Linux64.  */
>>> +#undef rs6000_relative_jumptables
>>> +#define rs6000_relative_jumptables 0
>> (That's not what it's called...  Just don't say the "for..." at all?
>> It is clear from what file it is in.)
>>
>>>   /* 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
>> Not sure that is correct.  Maybe the patch using rodata (.data.rel.ro)
>> should be a separate patch?
>>
>>>   /* 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
>> This should depend on the new flag?
>>
>>> +/* 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)
>> rs6000_relative_jumptables ? SImode : Pmode;
>>
>>> +      if (rs6000_relative_jumptables)
>>> +    {
>>> +      if (TARGET_32BIT)
>>> +        emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
>>> +      else
>>> +        emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
>>> +    }
>> Hrm, I guess we should make that a parameterized name (future work,
>> don't do it now :-) )
>>
>>> +(define_expand "absolute_tablejumpsi"
>> Don't prefix names; it should start with "tablejump".
>>
>>
>> Segher

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

	* config/rs6000/rs6000-protos.h (rs6000_output_addr_vec_elt): Declare.
	* config/rs6000/rs6000.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC):
	Define.
	(rs6000_gen_pic_addr_diff_vec, rs6000_output_addr_vec_elt): Implement.
	* config/rs6000/rs6000.h (CASE_VECTOR_PC_RELATIVE,
	CASE_VECTOR_MODE, ASM_OUTPUT_ADDR_VEC_ELT): Define.
	* config/rs6000/rs6000.md (tablejumpsi_absolute,
	tablejumpsi_nospec_absolute, tablejumpdi_absolute,
	tablejumpdi_nospec_absolute): New expanders.
	* config/rs6000/rs6000.opt (mrelative-jumptables): Add
	mrelative-jumptables.

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

diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 5508484ba19..62564dd67f2 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..94d1e650b94 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,27 @@ 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..6759ac0de11 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1752,15 +1752,16 @@ 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
-
 /* 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 rs6000_relative_jumptables
+
+/* 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 : Pmode)
 
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 0
@@ -2190,6 +2191,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..7381c4909c3 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -12668,19 +12668,35 @@
 {
   if (rs6000_speculate_indirect_jumps)
     {
-      if (TARGET_32BIT)
-      	emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
+      if (rs6000_relative_jumptables)
+	{
+	  if (TARGET_32BIT)
+	    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
+	  else
+	    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
+	}
+      else if (TARGET_32BIT)
+	emit_jump_insn (gen_tablejumpsi_absolute (operands[0], operands[1]));
       else
-	emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
+	emit_jump_insn (gen_tablejumpdi_absolute (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);
+      if (rs6000_relative_jumptables)
+	{
+	  if (TARGET_32BIT)
+	    jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
+	  else
+	    jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+	}
+      else if (TARGET_32BIT)
+	jump = gen_tablejumpsi_nospec_absolute (operands[0], operands[1],
+						ccreg);
       else
-	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+	jump = gen_tablejumpdi_nospec_absolute (operands[0], operands[1],
+						ccreg);
       emit_jump_insn (jump);
     }
   DONE;
@@ -12693,13 +12709,26 @@
    (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 "tablejumpsi_absolute"
+  [(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,32 +12737,59 @@
 		   (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 "tablejumpsi_nospec_absolute"
+  [(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")))
+	(sign_extend:DI (match_operand:SI 0 "lwa_operand")))
    (set (match_dup 3)
 	(plus:DI (match_dup 4)
 		 (match_dup 2)))
    (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 "tablejumpdi_absolute"
+  [(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")))
+	(sign_extend:DI (match_operand:SI 0 "lwa_operand")))
    (set (match_dup 4)
 	(plus:DI (match_dup 5)
 		 (match_dup 3)))
@@ -12741,13 +12797,27 @@
 		   (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 "tablejumpdi_nospec_absolute"
+  [(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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  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
  1 sibling, 1 reply; 13+ messages in thread
From: Segher Boessenkool @ 2020-09-28 22:46 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: gcc-patches, wschmidt

Hi hao Chen,

On Wed, Sep 09, 2020 at 04:55:29PM +0800, HAO CHEN GUI wrote:
>     Thanks for your advice. I removed macros defined in linux64.h and 
> linux.h. So they take relative jump tables by default. When 
> no-relative-jumptables is set, the absolute jump tables are taken. All 
> things relevant to section relocations are put in another patch. Thanks 
> again.

[ Please do not insert patches into discussions ]

> +/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC.
> +   Return true if rs6000_relative_jumptables is set.  */

Don't just say what the code does (we can see that ;-) ); say *why*.
Of course it is terribly simple in this case, so maybe just that first
line is plenty.

> +/* 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 : Pmode)

If TARGET_32BIT is true, SImode and Pmode are the same, so this is
simpler said as

#define CASE_VECTOR_MODE (rs6000_relative_jumptables ? SImode : Pmode)


I'll have the tablejump* patterns converted to paremeterized names
hopefully tonight or tomorrow, which will make your patch much easier
to read.  It looks like it will be fine, thanks :-)


Segher

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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  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-23 22:25             ` Segher Boessenkool
  0 siblings, 2 replies; 13+ messages in thread
From: HAO CHEN GUI @ 2020-10-15  8:46 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, wschmidt

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

Segher,

     I re-wrote the patch based on parameterized name.

     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.


On 29/9/2020 上午 6:46, Segher Boessenkool wrote:
> Hi hao Chen,
>
> On Wed, Sep 09, 2020 at 04:55:29PM +0800, HAO CHEN GUI wrote:
>>      Thanks for your advice. I removed macros defined in linux64.h and
>> linux.h. So they take relative jump tables by default. When
>> no-relative-jumptables is set, the absolute jump tables are taken. All
>> things relevant to section relocations are put in another patch. Thanks
>> again.
> [ Please do not insert patches into discussions ]
>
>> +/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC.
>> +   Return true if rs6000_relative_jumptables is set.  */
> Don't just say what the code does (we can see that ;-) ); say *why*.
> Of course it is terribly simple in this case, so maybe just that first
> line is plenty.
>
>> +/* 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 : Pmode)
> If TARGET_32BIT is true, SImode and Pmode are the same, so this is
> simpler said as
>
> #define CASE_VECTOR_MODE (rs6000_relative_jumptables ? SImode : Pmode)
>
>
> I'll have the tablejump* patterns converted to paremeterized names
> hopefully tonight or tomorrow, which will make your patch much easier
> to read.  It looks like it will be fine, thanks :-)
>
>
> Segher

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

	* config/rs6000/rs6000-protos.h (rs6000_output_addr_vec_elt): Declare.
	* config/rs6000/rs6000.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC):
	Define.
	(rs6000_gen_pic_addr_diff_vec, rs6000_output_addr_vec_elt): Implement.
	* config/rs6000/rs6000.h (CASE_VECTOR_PC_RELATIVE,
	CASE_VECTOR_MODE, ASM_OUTPUT_ADDR_VEC_ELT): Define.
	* config/rs6000/rs6000.md (tablejump<mode>_absolute,
	tablejump<mode>_absolute_nospec): New expanders.
	* config/rs6000/rs6000.opt (mrelative-jumptables): Add
	mrelative-jumptables.

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

diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 25fa5dd57cd..49ab51042c5 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -155,6 +155,7 @@ extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool);
 extern bool rs6000_function_pcrel_p (struct function *);
 extern bool rs6000_pcrel_p (void);
 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
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b58eeae2b98..7e441f7e730 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1367,6 +1367,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
 
@@ -27053,6 +27056,27 @@ rs6000_emit_xxspltidp_v2df (rtx dst, long value)
   emit_insn( gen_xxspltidp_v2df_inst (dst, GEN_INT (value)));
 }
 
+/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC.
+   Marco relative jumpstables indicates addr_diff_vec or addr_vec.  */
+
+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 bbd8060e143..4a948e25f71 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1754,15 +1754,15 @@ 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
-
 /* 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 rs6000_relative_jumptables
+
+/* Specify the machine mode that this machine uses
+   for the index in the tablejump instruction.  */
+#define CASE_VECTOR_MODE (rs6000_relative_jumptables ? SImode : Pmode)
 
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 0
@@ -2192,6 +2192,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 779bfd11237..4f1265d6437 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -12697,15 +12697,27 @@
   ""
 {
   if (rs6000_speculate_indirect_jumps)
-    emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
+    {
+      if (rs6000_relative_jumptables)
+	emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
+      else
+	emit_jump_insn (gen_tablejump_absolute (Pmode, 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);
+      if (rs6000_relative_jumptables)
+	{
+	  if (TARGET_32BIT)
+	    jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
+	  else
+	    jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+	}
       else
-	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+	jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
+					      ccreg);
       emit_jump_insn (jump);
     }
   DONE;
@@ -12714,7 +12726,7 @@
 (define_expand "@tablejump<mode>_normal"
   [(use (match_operand:SI 0))
    (use (match_operand:P 1))]
-  "rs6000_speculate_indirect_jumps"
+  "rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
 {
   rtx off;
   operands[0] = force_reg (SImode, operands[0]);
@@ -12735,11 +12747,23 @@
   DONE;
 })
 
+(define_expand "@tablejump<mode>_absolute"
+  [(use (match_operand:P 0))
+   (use (match_operand:P 1))]
+  "rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+{
+  rtx addr = gen_reg_rtx (Pmode);
+  emit_move_insn (addr, operands[0]);
+
+  emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
+  DONE;
+})
+
 (define_expand "@tablejump<mode>_nospec"
   [(use (match_operand:SI 0))
    (use (match_operand:P 1))
    (use (match_operand:CC 2))]
-  "!rs6000_speculate_indirect_jumps"
+  "!rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
 {
   rtx off;
   operands[0] = force_reg (SImode, operands[0]);
@@ -12761,6 +12785,20 @@
   DONE;
 })
 
+(define_expand "@tablejump<mode>_absolute_nospec"
+  [(use (match_operand:P 0))
+   (use (match_operand:P 1))
+   (use (match_operand:CC 2))]
+  "!rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+{
+  rtx addr = gen_reg_rtx (Pmode);
+  emit_move_insn (addr, operands[0]);
+
+  emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
+					     operands[2]));
+  DONE;
+})
+
 (define_insn "@tablejump<mode>_insn_normal"
   [(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 b2a70e88ca8..2888172cb27 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -589,3 +589,6 @@ Generate (do not generate) pc-relative memory addressing.
 mmma
 Target Report Mask(MMA) Var(rs6000_isa_flags)
 Generate (do not generate) MMA instructions.
+
+mrelative-jumptables
+Target Undocumented Var(rs6000_relative_jumptables) Init(1) Save

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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  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
  1 sibling, 2 replies; 13+ messages in thread
From: HAO CHEN GUI @ 2020-11-06  1:02 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, wschmidt

Hi,

Gentle ping this:

https://gcc.gnu.org/pipermail/gcc-patches/2020-October/556236.html

Thanks.

Gui Haochen


On 15/10/2020 下午 4:46, HAO CHEN GUI wrote:
> Segher,
>
>     I re-wrote the patch based on parameterized name.
>
>     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.
>
>
> On 29/9/2020 上午 6:46, Segher Boessenkool wrote:
>> Hi hao Chen,
>>
>> On Wed, Sep 09, 2020 at 04:55:29PM +0800, HAO CHEN GUI wrote:
>>>      Thanks for your advice. I removed macros defined in linux64.h and
>>> linux.h. So they take relative jump tables by default. When
>>> no-relative-jumptables is set, the absolute jump tables are taken. All
>>> things relevant to section relocations are put in another patch. Thanks
>>> again.
>> [ Please do not insert patches into discussions ]
>>
>>> +/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC.
>>> +   Return true if rs6000_relative_jumptables is set.  */
>> Don't just say what the code does (we can see that ;-) ); say *why*.
>> Of course it is terribly simple in this case, so maybe just that first
>> line is plenty.
>>
>>> +/* 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 : Pmode)
>> If TARGET_32BIT is true, SImode and Pmode are the same, so this is
>> simpler said as
>>
>> #define CASE_VECTOR_MODE (rs6000_relative_jumptables ? SImode : Pmode)
>>
>>
>> I'll have the tablejump* patterns converted to paremeterized names
>> hopefully tonight or tomorrow, which will make your patch much easier
>> to read.  It looks like it will be fine, thanks :-)
>>
>>
>> Segher

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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  2020-11-06  1:02             ` HAO CHEN GUI
@ 2020-11-16  6:56               ` HAO CHEN GUI
  2020-11-23  2:41               ` HAO CHEN GUI
  1 sibling, 0 replies; 13+ messages in thread
From: HAO CHEN GUI @ 2020-11-16  6:56 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, wschmidt

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

Hi,

Gentle ping this:

https://gcc.gnu.org/pipermail/gcc-patches/2020-October/556236.html

Thanks.

Gui Haochen

On 6/11/2020 上午 9:02, HAO CHEN GUI wrote:
> Hi,
>
> Gentle ping this:
>
> https://gcc.gnu.org/pipermail/gcc-patches/2020-October/556236.html
>
> Thanks.
>
> Gui Haochen
>
>
> On 15/10/2020 下午 4:46, HAO CHEN GUI wrote:
>> Segher,
>>
>>     I re-wrote the patch based on parameterized name.
>>
>>     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.
>>
>>
>> On 29/9/2020 上午 6:46, Segher Boessenkool wrote:
>>> Hi hao Chen,
>>>
>>> On Wed, Sep 09, 2020 at 04:55:29PM +0800, HAO CHEN GUI wrote:
>>>>      Thanks for your advice. I removed macros defined in linux64.h and
>>>> linux.h. So they take relative jump tables by default. When
>>>> no-relative-jumptables is set, the absolute jump tables are taken. All
>>>> things relevant to section relocations are put in another patch. 
>>>> Thanks
>>>> again.
>>> [ Please do not insert patches into discussions ]
>>>
>>>> +/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC.
>>>> +   Return true if rs6000_relative_jumptables is set.  */
>>> Don't just say what the code does (we can see that ;-) ); say *why*.
>>> Of course it is terribly simple in this case, so maybe just that first
>>> line is plenty.
>>>
>>>> +/* 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 : Pmode)
>>> If TARGET_32BIT is true, SImode and Pmode are the same, so this is
>>> simpler said as
>>>
>>> #define CASE_VECTOR_MODE (rs6000_relative_jumptables ? SImode : Pmode)
>>>
>>>
>>> I'll have the tablejump* patterns converted to paremeterized names
>>> hopefully tonight or tomorrow, which will make your patch much easier
>>> to read.  It looks like it will be fine, thanks :-)
>>>
>>>
>>> Segher

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

	* config/rs6000/rs6000-protos.h (rs6000_output_addr_vec_elt): Declare.
	* config/rs6000/rs6000.c (TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC):
	Define.
	(rs6000_gen_pic_addr_diff_vec, rs6000_output_addr_vec_elt): Implement.
	* config/rs6000/rs6000.h (CASE_VECTOR_PC_RELATIVE,
	CASE_VECTOR_MODE, ASM_OUTPUT_ADDR_VEC_ELT): Define.
	* config/rs6000/rs6000.md (tablejump<mode>_absolute,
	tablejump<mode>_absolute_nospec): New expanders.
	* config/rs6000/rs6000.opt (mrelative-jumptables): Add
	mrelative-jumptables.

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

diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 25fa5dd57cd..49ab51042c5 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -155,6 +155,7 @@ extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool);
 extern bool rs6000_function_pcrel_p (struct function *);
 extern bool rs6000_pcrel_p (void);
 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
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b58eeae2b98..7e441f7e730 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1367,6 +1367,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
 
@@ -27053,6 +27056,27 @@ rs6000_emit_xxspltidp_v2df (rtx dst, long value)
   emit_insn( gen_xxspltidp_v2df_inst (dst, GEN_INT (value)));
 }
 
+/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC.
+   Marco relative jumpstables indicates addr_diff_vec or addr_vec.  */
+
+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 bbd8060e143..4a948e25f71 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1754,15 +1754,15 @@ 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
-
 /* 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 rs6000_relative_jumptables
+
+/* Specify the machine mode that this machine uses
+   for the index in the tablejump instruction.  */
+#define CASE_VECTOR_MODE (rs6000_relative_jumptables ? SImode : Pmode)
 
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 0
@@ -2192,6 +2192,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 779bfd11237..4f1265d6437 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -12697,15 +12697,27 @@
   ""
 {
   if (rs6000_speculate_indirect_jumps)
-    emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
+    {
+      if (rs6000_relative_jumptables)
+	emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
+      else
+	emit_jump_insn (gen_tablejump_absolute (Pmode, 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);
+      if (rs6000_relative_jumptables)
+	{
+	  if (TARGET_32BIT)
+	    jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
+	  else
+	    jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+	}
       else
-	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
+	jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
+					      ccreg);
       emit_jump_insn (jump);
     }
   DONE;
@@ -12714,7 +12726,7 @@
 (define_expand "@tablejump<mode>_normal"
   [(use (match_operand:SI 0))
    (use (match_operand:P 1))]
-  "rs6000_speculate_indirect_jumps"
+  "rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
 {
   rtx off;
   operands[0] = force_reg (SImode, operands[0]);
@@ -12735,11 +12747,23 @@
   DONE;
 })
 
+(define_expand "@tablejump<mode>_absolute"
+  [(use (match_operand:P 0))
+   (use (match_operand:P 1))]
+  "rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+{
+  rtx addr = gen_reg_rtx (Pmode);
+  emit_move_insn (addr, operands[0]);
+
+  emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
+  DONE;
+})
+
 (define_expand "@tablejump<mode>_nospec"
   [(use (match_operand:SI 0))
    (use (match_operand:P 1))
    (use (match_operand:CC 2))]
-  "!rs6000_speculate_indirect_jumps"
+  "!rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
 {
   rtx off;
   operands[0] = force_reg (SImode, operands[0]);
@@ -12761,6 +12785,20 @@
   DONE;
 })
 
+(define_expand "@tablejump<mode>_absolute_nospec"
+  [(use (match_operand:P 0))
+   (use (match_operand:P 1))
+   (use (match_operand:CC 2))]
+  "!rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
+{
+  rtx addr = gen_reg_rtx (Pmode);
+  emit_move_insn (addr, operands[0]);
+
+  emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
+					     operands[2]));
+  DONE;
+})
+
 (define_insn "@tablejump<mode>_insn_normal"
   [(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 b2a70e88ca8..2888172cb27 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -589,3 +589,6 @@ Generate (do not generate) pc-relative memory addressing.
 mmma
 Target Report Mask(MMA) Var(rs6000_isa_flags)
 Generate (do not generate) MMA instructions.
+
+mrelative-jumptables
+Target Undocumented Var(rs6000_relative_jumptables) Init(1) Save

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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  2020-11-06  1:02             ` HAO CHEN GUI
  2020-11-16  6:56               ` HAO CHEN GUI
@ 2020-11-23  2:41               ` HAO CHEN GUI
  1 sibling, 0 replies; 13+ messages in thread
From: HAO CHEN GUI @ 2020-11-23  2:41 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, wschmidt

Hi,

Gentle ping this:

https://gcc.gnu.org/pipermail/gcc-patches/2020-October/556236.html

Thanks.

Gui Haochen

On 6/11/2020 上午 9:02, HAO CHEN GUI wrote:
> Hi,
>
> Gentle ping this:
>
> https://gcc.gnu.org/pipermail/gcc-patches/2020-October/556236.html
>
> Thanks.
>
> Gui Haochen
>
>
> On 15/10/2020 下午 4:46, HAO CHEN GUI wrote:
>> Segher,
>>
>>     I re-wrote the patch based on parameterized name.
>>
>>     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.
>>
>>
>> On 29/9/2020 上午 6:46, Segher Boessenkool wrote:
>>> Hi hao Chen,
>>>
>>> On Wed, Sep 09, 2020 at 04:55:29PM +0800, HAO CHEN GUI wrote:
>>>>      Thanks for your advice. I removed macros defined in linux64.h and
>>>> linux.h. So they take relative jump tables by default. When
>>>> no-relative-jumptables is set, the absolute jump tables are taken. All
>>>> things relevant to section relocations are put in another patch. 
>>>> Thanks
>>>> again.
>>> [ Please do not insert patches into discussions ]
>>>
>>>> +/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC.
>>>> +   Return true if rs6000_relative_jumptables is set.  */
>>> Don't just say what the code does (we can see that ;-) ); say *why*.
>>> Of course it is terribly simple in this case, so maybe just that first
>>> line is plenty.
>>>
>>>> +/* 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 : Pmode)
>>> If TARGET_32BIT is true, SImode and Pmode are the same, so this is
>>> simpler said as
>>>
>>> #define CASE_VECTOR_MODE (rs6000_relative_jumptables ? SImode : Pmode)
>>>
>>>
>>> I'll have the tablejump* patterns converted to paremeterized names
>>> hopefully tonight or tomorrow, which will make your patch much easier
>>> to read.  It looks like it will be fine, thanks :-)
>>>
>>>
>>> Segher

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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  2020-10-15  8:46           ` HAO CHEN GUI
  2020-11-06  1:02             ` HAO CHEN GUI
@ 2020-11-23 22:25             ` Segher Boessenkool
  2020-11-27  1:16               ` HAO CHEN GUI
  1 sibling, 1 reply; 13+ messages in thread
From: Segher Boessenkool @ 2020-11-23 22:25 UTC (permalink / raw)
  To: HAO CHEN GUI; +Cc: gcc-patches, wschmidt

Hi!

Sorry this took so long.

On Thu, Oct 15, 2020 at 04:46:01PM +0800, HAO CHEN GUI wrote:
> On 29/9/2020 上午 6:46, Segher Boessenkool wrote:
> >[ Please do not insert patches into discussions ]

So, please send new patches as a new thread.  This makes it much easier
to handle.  If you want to reply to something in the old thread just do
it there, but send the new patch not as a reply.

> 	* config/rs6000/rs6000.opt (mrelative-jumptables): Add
> 	mrelative-jumptables.

Just "New." or "New flag." or similar?

> +/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC.
> +   Marco relative jumpstables indicates addr_diff_vec or addr_vec.  */

The documentation says
  Return true to generate ADDR_DIF_VEC table or false to generate
  ADDR_VEC table for jumps in case of -fPIC.
but you can just leave out that last line completely.

> +      if (rs6000_relative_jumptables)
> +	{
> +	  if (TARGET_32BIT)
> +	    jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
> +	  else
> +	    jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
> +	}
>        else
> -	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
> +	jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
> +					      ccreg);
>        emit_jump_insn (jump);

It now is
  @tablejump<mode>_nospec
so this code will become something like

      if (rs6000_relative_jumptables)
	jump = gen_tablejumpsi_nospec (Pmode, operands[0], operands[1], ccreg);
      else
	jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
					      ccreg);
      emit_jump_insn (jump);


Okay for trunk with those changes.  Thank you!


Segher

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

* Re: [PATCH, rs6000] Add non-relative jump table support on Power Linux
  2020-11-23 22:25             ` Segher Boessenkool
@ 2020-11-27  1:16               ` HAO CHEN GUI
  0 siblings, 0 replies; 13+ messages in thread
From: HAO CHEN GUI @ 2020-11-27  1:16 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, wschmidt

Segher,

   Thanks for your comments. I have modified the patch according to your 
advice and committed.

On 24/11/2020 上午 6:25, Segher Boessenkool wrote:
> Hi!
>
> Sorry this took so long.
>
> On Thu, Oct 15, 2020 at 04:46:01PM +0800, HAO CHEN GUI wrote:
>> On 29/9/2020 上午 6:46, Segher Boessenkool wrote:
>>> [ Please do not insert patches into discussions ]
> So, please send new patches as a new thread.  This makes it much easier
> to handle.  If you want to reply to something in the old thread just do
> it there, but send the new patch not as a reply.
>
>> 	* config/rs6000/rs6000.opt (mrelative-jumptables): Add
>> 	mrelative-jumptables.
> Just "New." or "New flag." or similar?
>
>> +/* Implement TARGET_ASM_GENERATE_PIC_ADDR_DIFF_VEC.
>> +   Marco relative jumpstables indicates addr_diff_vec or addr_vec.  */
> The documentation says
>    Return true to generate ADDR_DIF_VEC table or false to generate
>    ADDR_VEC table for jumps in case of -fPIC.
> but you can just leave out that last line completely.
>
>> +      if (rs6000_relative_jumptables)
>> +	{
>> +	  if (TARGET_32BIT)
>> +	    jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
>> +	  else
>> +	    jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
>> +	}
>>         else
>> -	jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
>> +	jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
>> +					      ccreg);
>>         emit_jump_insn (jump);
> It now is
>    @tablejump<mode>_nospec
> so this code will become something like
>
>        if (rs6000_relative_jumptables)
> 	jump = gen_tablejumpsi_nospec (Pmode, operands[0], operands[1], ccreg);
>        else
> 	jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
> 					      ccreg);
>        emit_jump_insn (jump);
>
>
> Okay for trunk with those changes.  Thank you!
>
>
> Segher

^ 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).