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

Reply via email to