This patch updates the basic support for pc-relative addressing that will be
added in a future machine.

It was originally proposed as patch #4:
https://gcc.gnu.org/ml/gcc-patches/2019-06/msg01866.html

Segher suggested that I split out moving create_TOC_reference back to rs6000.c
as a separate patch, which I did in this patch that has been committed:
https://gcc.gnu.org/ml/gcc-patches/2019-07/msg00719.html

In working on the other suggestions from Segher about the second argument to
create_TOC_reference (which is where to put the HIGH value after register
allocation), I came to the conclusion it wasn't worth it to try and combine TOC
and pc-relative addressing.  There are two places in rs6000_emit_move that deal
with the creation of TOC/pc-relative addressing.

There is also one place in rs6000.md that created TOC addressing that needed to
support pc-relative addressing also.  It does the compare of two __ibm128
floating point values when the -mcompat-xl switch is used, and the comparison
needs to compare the values against 0 and +infinity, and it needs to load up
the two constants.

Instead of trying to combine the two addressing forms, I added separate support
for pc-relative addressing, and added extra checks in supporting TOC
addressing.

The one place where I combined TOC and pc-relative addressing is using a common
function to set the memory alias set group.  Originally it was called
get_TOC_alias_set, and I renamed it to get_data_alias_set and I changed all of
the callers.

There will be several other patches before all of the pc-relative support is
available and turned on by default.

I have bootstraped the compiler on a little endian power8 system and there were
no regressions in the test suite.  Can I check it into the trunk?

2019-07-09  Michael Meissner  <meiss...@linux.ibm.com>

        * config/rs6000/rs6000-protos.h (get_data_alias_set): Rename
        get_TOC_alias_set for use with both TOC & pc-relative addressing.
        * config/rs6000/rs6000.c (create_TOC_reference): Add gcc_assert.
        (rs6000_legitimize_address): Add check for not pc-relative in TOC
        support.
        (rs6000_legitimize_tls_address_aix): Call get_data_alias_set
        instead of get_TOC_alias_set.
        (use_toc_relative_ref): Add check for SYMBOL_REF and not
        pc-relative to simplify callers.  Make tests easier to
        understand.
        (use_pc_relative_ref): New helper function.
        (rs6000_emit_move): Add basic support for pc-relative addressing.
        Call get_data_alias_set instead of get_TOC_alias_set.
        (data_alias_set): Rename static variable.
        (get_data_alias_set): Rename get_TOC_alias_set since it is now
        used for both TOC and pc-relative addressing.
        * config/rs6000/rs6000.md (cmp<mode>_internal2): Add support for
        pc-relative addressing.  Call get_data_alias_set instead of
        get_TOC_alias_set.

Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h   (revision 273255)
+++ gcc/config/rs6000/rs6000-protos.h   (working copy)
@@ -189,7 +189,7 @@ extern void rs6000_gen_section_name (cha
 extern void output_function_profiler (FILE *, int);
 extern void output_profile_hook  (int);
 extern int rs6000_trampoline_size (void);
-extern alias_set_type get_TOC_alias_set (void);
+extern alias_set_type get_data_alias_set (void);
 extern void rs6000_emit_prologue (void);
 extern void rs6000_emit_load_toc_table (int);
 extern unsigned int rs6000_dbx_register_number (unsigned int, unsigned int);
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 273310)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -7740,6 +7740,8 @@ create_TOC_reference (rtx symbol, rtx la
 {
   rtx tocrel, tocreg, hi;
 
+  gcc_assert (TARGET_TOC && !TARGET_PCREL);
+
   if (TARGET_DEBUG_ADDR)
     {
       if (SYMBOL_REF_P (symbol))
@@ -8137,7 +8139,7 @@ rs6000_legitimize_address (rtx x, rtx ol
        emit_insn (gen_macho_high (reg, x));
       return gen_rtx_LO_SUM (Pmode, reg, x);
     }
-  else if (TARGET_TOC
+  else if (TARGET_TOC && !TARGET_PCREL
           && SYMBOL_REF_P (x)
           && constant_pool_expr_p (x)
           && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
@@ -8441,7 +8443,7 @@ rs6000_legitimize_tls_address_aix (rtx a
     {
       tocref = create_TOC_reference (XEXP (sym, 0), NULL_RTX);
       mem = gen_const_mem (Pmode, tocref);
-      set_mem_alias_set (mem, get_TOC_alias_set ());
+      set_mem_alias_set (mem, get_data_alias_set ());
     }
   else
     return sym;
@@ -8459,7 +8461,7 @@ rs6000_legitimize_tls_address_aix (rtx a
       SYMBOL_REF_FLAGS (modaddr) |= SYMBOL_FLAG_LOCAL;
       tocref = create_TOC_reference (modaddr, NULL_RTX);
       rtx modmem = gen_const_mem (Pmode, tocref);
-      set_mem_alias_set (modmem, get_TOC_alias_set ());
+      set_mem_alias_set (modmem, get_data_alias_set ());
       
       rtx modreg = gen_reg_rtx (Pmode);
       emit_insn (gen_rtx_SET (modreg, modmem));
@@ -8760,12 +8762,34 @@ rs6000_cannot_force_const_mem (machine_m
 static bool
 use_toc_relative_ref (rtx sym, machine_mode mode)
 {
-  return ((constant_pool_expr_p (sym)
-          && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym),
-                                              get_pool_mode (sym)))
-         || (TARGET_CMODEL == CMODEL_MEDIUM
-             && SYMBOL_REF_LOCAL_P (sym)
-             && GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT));
+  if (!SYMBOL_REF_P (sym) || TARGET_PCREL || !TARGET_TOC)
+    return false;
+
+  if (constant_pool_expr_p (sym)
+      && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym),
+                                         get_pool_mode (sym)))
+    return true;
+
+  return (TARGET_CMODEL == CMODEL_MEDIUM && SYMBOL_REF_LOCAL_P (sym)
+         && GET_MODE_SIZE (mode) <= POWERPC64_TOC_POINTER_ALIGNMENT);
+}
+
+/* Return true iff the given SYMBOL_REF refers to a constant pool entry that we
+   have put in the pc-relative constant area, or for cmodel=medium, if the
+   SYMBOL_REF can be addressed via pc-relative instructions.  */
+
+static bool
+use_pc_relative_ref (rtx sym)
+{
+  if (!SYMBOL_REF_P (sym) || !TARGET_PCREL)
+    return false;
+
+  if (constant_pool_expr_p (sym)
+      && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym),
+                                         get_pool_mode (sym)))
+    return true;
+
+  return (TARGET_CMODEL == CMODEL_MEDIUM && SYMBOL_REF_LOCAL_P (sym));
 }
 
 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
@@ -9865,10 +9889,14 @@ rs6000_emit_move (rtx dest, rtx source,
       /* If this is a SYMBOL_REF that refers to a constant pool entry,
         and we have put it in the TOC, we just need to make a TOC-relative
         reference to it.  */
-      if (TARGET_TOC
-         && SYMBOL_REF_P (operands[1])
-         && use_toc_relative_ref (operands[1], mode))
+      if (use_toc_relative_ref (operands[1], mode))
        operands[1] = create_TOC_reference (operands[1], operands[0]);
+
+      /* If this is a pc-relative reference, we don't have to do anything
+        fancy.  */
+      else if (use_pc_relative_ref (operands[1]))
+       ;
+
       else if (mode == Pmode
               && CONSTANT_P (operands[1])
               && GET_CODE (operands[1]) != HIGH
@@ -9919,14 +9947,18 @@ rs6000_emit_move (rtx dest, rtx source,
 
          operands[1] = force_const_mem (mode, operands[1]);
 
-         if (TARGET_TOC
-             && SYMBOL_REF_P (XEXP (operands[1], 0))
-             && use_toc_relative_ref (XEXP (operands[1], 0), mode))
+         rtx addr = XEXP (operands[1], 0);
+         if (use_toc_relative_ref (addr, mode))
            {
-             rtx tocref = create_TOC_reference (XEXP (operands[1], 0),
-                                                operands[0]);
+             rtx tocref = create_TOC_reference (addr, operands[0]);
              operands[1] = gen_const_mem (mode, tocref);
-             set_mem_alias_set (operands[1], get_TOC_alias_set ());
+             set_mem_alias_set (operands[1], get_data_alias_set ());
+           }
+
+         else if (use_pc_relative_ref (addr))
+           {
+             operands[1] = gen_const_mem (mode, addr);
+             set_mem_alias_set (operands[1], get_data_alias_set ());
            }
        }
       break;
@@ -23732,14 +23764,16 @@ rs6000_split_multireg_move (rtx dst, rtx
     }
 }
 
-static GTY(()) alias_set_type set = -1;
+/* Return the alias set for constants stored in either the TOC or via
+   pc-relative addressing.  */
+static GTY(()) alias_set_type data_alias_set = -1;
 
 alias_set_type
-get_TOC_alias_set (void)
+get_data_alias_set (void)
 {
-  if (set == -1)
-    set = new_alias_set ();
-  return set;
+  if (data_alias_set == -1)
+    data_alias_set = new_alias_set ();
+  return data_alias_set;
 }
 
 /* Return the internal arg pointer used for function incoming
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 273255)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -11606,15 +11606,23 @@ (define_insn_and_split "*cmp<mode>_inter
   operands[15] = force_const_mem (DFmode,
                                  const_double_from_real_value (dconst0,
                                                                DFmode));
-  if (TARGET_TOC)
+  if (TARGET_PCREL)
+    {
+      operands[14] = gen_const_mem (DFmode, XEXP (operands[14], 0));
+      operands[15] = gen_const_mem (DFmode, XEXP (operands[15], 0));
+      set_mem_alias_set (operands[14], get_data_alias_set ());
+      set_mem_alias_set (operands[15], get_data_alias_set ());
+    }
+
+  else if (TARGET_TOC)
     {
       rtx tocref;
       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
       operands[14] = gen_const_mem (DFmode, tocref);
       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
       operands[15] = gen_const_mem (DFmode, tocref);
-      set_mem_alias_set (operands[14], get_TOC_alias_set ());
-      set_mem_alias_set (operands[15], get_TOC_alias_set ());
+      set_mem_alias_set (operands[14], get_data_alias_set ());
+      set_mem_alias_set (operands[15], get_data_alias_set ());
     }
 })
 


-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797

Reply via email to