constraints.md ("S"): Match r0rel_constant_p too.
authorSandra Loosemore <sandra@codesourcery.com>
Thu, 26 Oct 2017 20:52:15 +0000 (16:52 -0400)
committerSandra Loosemore <sandra@gcc.gnu.org>
Thu, 26 Oct 2017 20:52:15 +0000 (16:52 -0400)
2017-10-26  Sandra Loosemore  <sandra@codesourcery.com>

gcc/
* config/nios2/constraints.md ("S"): Match r0rel_constant_p too.
* config/nios2/nios2-protos.h (r0rel_constant_p): Declare.
* config/nios2/nios2.c: (nios2_r0rel_sec_regex): New.
(nios2_option_overide): Initialize it.  Don't allow R0-relative
addressing with PIC.
(nios2_rtx_costs): Handle r0rel_constant_p like gprel_constant_p.
(nios2_symbolic_constant_p): Likewise.
(nios2_legitimate_address_p): Likewise.
(nios2_r0rel_section_name_p): New.
(nios2_symbol_ref_in_r0rel_data_p): New.
(nios2_emit_move_sequence): Handle r0rel_constant_p.
(r0rel_constant_p): New.
(nios2_print_operand_address): Handle r0rel_constant_p.
(nios2_cdx_narrow_form_p): Likewise.
* config/nios2/nios2.opt (mr0rel-sec=): New option.
* doc/invoke.texi (Option Summary): Add -mr0rel-sec.
(Nios II Options): Document -mr0rel-sec.

gcc/testsuite/
* gcc.target/nios2/gpopt-r0rel-sec.c: New.

From-SVN: r254124

gcc/ChangeLog
gcc/config/nios2/constraints.md
gcc/config/nios2/nios2-protos.h
gcc/config/nios2/nios2.c
gcc/config/nios2/nios2.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/nios2/gpopt-r0rel-sec.c [new file with mode: 0644]

index 7ee9da214c4a420a87fff740c987648c19e10389..558ec9bf7f270a5d5522decc18b493484500dfb6 100644 (file)
@@ -1,3 +1,23 @@
+2017-10-26  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * config/nios2/constraints.md ("S"): Match r0rel_constant_p too.
+       * config/nios2/nios2-protos.h (r0rel_constant_p): Declare.
+       * config/nios2/nios2.c: (nios2_r0rel_sec_regex): New.
+       (nios2_option_overide): Initialize it.  Don't allow R0-relative 
+       addressing with PIC.
+       (nios2_rtx_costs): Handle r0rel_constant_p like gprel_constant_p.
+       (nios2_symbolic_constant_p): Likewise.
+       (nios2_legitimate_address_p): Likewise.
+       (nios2_r0rel_section_name_p): New.
+       (nios2_symbol_ref_in_r0rel_data_p): New.
+       (nios2_emit_move_sequence): Handle r0rel_constant_p.
+       (r0rel_constant_p): New.
+       (nios2_print_operand_address): Handle r0rel_constant_p.
+       (nios2_cdx_narrow_form_p): Likewise.
+       * config/nios2/nios2.opt (mr0rel-sec=): New option.
+       * doc/invoke.texi (Option Summary): Add -mr0rel-sec.
+       (Nios II Options): Document -mr0rel-sec.
+
 2017-10-26  Sandra Loosemore  <sandra@codesourcery.com>
 
        * config/nios2/nios2.c: Include xregex.h.
index c6c539265ace00376df99bc8523ab91f0d7b5081..51f71cf742eb119ba36cecfeab2ca210e84e802a 100644 (file)
@@ -95,8 +95,8 @@
        (match_test "TARGET_ARCH_R2 && ANDCLEAR_INT (ival)")))
 
 (define_constraint "S"
-  "An immediate stored in small data, accessible by GP."
-  (match_test "gprel_constant_p (op)"))
+  "An immediate stored in small data, accessible by GP, or by offset from r0."
+  (match_test "gprel_constant_p (op) || r0rel_constant_p (op)"))
 
 (define_constraint "T"
   "A constant unspec offset representing a relocation."
index 6df65bb800e3511245be26176611c545522d753a..84d450bfe94683ea97210551d26c2f65697c69b8 100644 (file)
@@ -52,6 +52,7 @@ extern const char * nios2_add_insn_asm (rtx_insn *, rtx *);
 
 extern bool nios2_legitimate_pic_operand_p (rtx);
 extern bool gprel_constant_p (rtx);
+extern bool r0rel_constant_p (rtx);
 extern bool nios2_regno_ok_for_base_p (int, bool);
 extern bool nios2_unspec_reloc_p (rtx);
 
index 3aade7b4543aed6a9dc0c54d79dca7732d5f22bb..cdd5e9aab658cefa32eafc8142de8d5ad0f4f8fa 100644 (file)
@@ -106,6 +106,7 @@ static bool custom_code_conflict = false;
 
 /* State for command-line options.  */
 regex_t nios2_gprel_sec_regex;
+regex_t nios2_r0rel_sec_regex;
 
 \f
 /* Definition of builtin function types for nios2.  */
@@ -1375,22 +1376,30 @@ nios2_option_override (void)
        nios2_gpopt_option = gpopt_local;
     }
 
-  /* GP-relative addressing doesn't make sense for PIC.  */
+  /* GP-relative and r0-relative addressing don't make sense for PIC.  */
   if (flag_pic)
-    { 
+    {
       if (nios2_gpopt_option != gpopt_none)
-        error ("-mgpopt not supported with PIC.");
+       error ("-mgpopt not supported with PIC.");
       if (nios2_gprel_sec)
-        error ("-mgprel-sec= not supported with PIC.");
+       error ("-mgprel-sec= not supported with PIC.");
+      if (nios2_r0rel_sec)
+       error ("-mr0rel-sec= not supported with PIC.");
     }
 
-  /* Process -mgprel-sec=.  */
+  /* Process -mgprel-sec= and -m0rel-sec=.  */
   if (nios2_gprel_sec)
     {
       if (regcomp (&nios2_gprel_sec_regex, nios2_gprel_sec, 
                   REG_EXTENDED | REG_NOSUB))
        error ("-mgprel-sec= argument is not a valid regular expression.");
     }
+  if (nios2_r0rel_sec)
+    {
+      if (regcomp (&nios2_r0rel_sec_regex, nios2_r0rel_sec, 
+                  REG_EXTENDED | REG_NOSUB))
+       error ("-mr0rel-sec= argument is not a valid regular expression.");
+    }
 
   /* If we don't have mul, we don't have mulx either!  */
   if (!TARGET_HAS_MUL && TARGET_HAS_MULX)
@@ -1478,7 +1487,7 @@ nios2_rtx_costs (rtx x, machine_mode mode,
       case SYMBOL_REF:
       case CONST:
       case CONST_DOUBLE:
-       if (gprel_constant_p (x))
+       if (gprel_constant_p (x) || r0rel_constant_p (x))
           {
             *total = COSTS_N_INSNS (1);
             return true;
@@ -2028,6 +2037,7 @@ nios2_symbolic_constant_p (rtx x)
       return (SYMBOL_REF_P (base)
                && !SYMBOL_REF_TLS_MODEL (base)
                && !gprel_constant_p (base)
+               && !r0rel_constant_p (base)
                && SMALL_INT (INTVAL (offset)));
     }
   return false;
@@ -2129,7 +2139,7 @@ nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
 
       /* Else, fall through.  */
     case CONST:
-      if (gprel_constant_p (operand))
+      if (gprel_constant_p (operand) || r0rel_constant_p (operand))
        return true;
 
       /* Else, fall through.  */
@@ -2294,6 +2304,14 @@ nios2_small_section_name_p (const char *section)
              && regexec (&nios2_gprel_sec_regex, section, 0, NULL, 0) == 0));
 }
 
+/* Return true if SECTION is a r0-relative section name.  */
+static bool
+nios2_r0rel_section_name_p (const char *section)
+{
+  return (nios2_r0rel_sec 
+         && regexec (&nios2_r0rel_sec_regex, section, 0, NULL, 0) == 0);
+}
+
 /* Return true if EXP should be placed in the small data section.  */
 static bool
 nios2_in_small_data_p (const_tree exp)
@@ -2400,6 +2418,33 @@ nios2_symbol_ref_in_small_data_p (rtx sym)
     }
 }
 
+/* Likewise for r0-relative addressing.  */
+static bool
+nios2_symbol_ref_in_r0rel_data_p (rtx sym)
+{
+  tree decl;
+
+  gcc_assert (GET_CODE (sym) == SYMBOL_REF);
+  decl = SYMBOL_REF_DECL (sym);
+
+  /* TLS variables are not accessed through r0.  */
+  if (SYMBOL_REF_TLS_MODEL (sym) != 0)
+    return false;
+
+  /* On Nios II R2, there is no r0-relative relocation that can be
+     used with "io" instructions.  So, if we are implicitly generating
+     those instructions, we cannot emit r0-relative accesses.  */
+  if (TARGET_ARCH_R2
+      && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE))
+    return false;
+
+  /* If the user has explicitly placed the symbol in a r0rel section
+     via an attribute, generate r0-relative addressing.  */
+  if (decl && DECL_SECTION_NAME (decl))
+    return nios2_r0rel_section_name_p (DECL_SECTION_NAME (decl));
+  return false;
+}
+
 /* Implement TARGET_SECTION_TYPE_FLAGS.  */
 
 static unsigned int
@@ -2633,8 +2678,9 @@ nios2_emit_move_sequence (rtx *operands, machine_mode mode)
              return true;
            }
        }
-      else if (gprel_constant_p (from))
-       /* Handled directly by movsi_internal as gp + offset.  */
+      else if (gprel_constant_p (from) || r0rel_constant_p (from))
+       /* Handled directly by movsi_internal as gp + offset 
+          or r0 + offset.  */
        ;
       else if (nios2_large_constant_p (from))
        /* This case covers either a regular symbol reference or an UNSPEC
@@ -2984,6 +3030,20 @@ gprel_constant_p (rtx op)
   return false;
 }
 
+/* Likewise if this is a zero-relative accessible reference.  */
+bool
+r0rel_constant_p (rtx op)
+{
+  if (GET_CODE (op) == SYMBOL_REF
+      && nios2_symbol_ref_in_r0rel_data_p (op))
+    return true;
+  else if (GET_CODE (op) == CONST
+           && GET_CODE (XEXP (op, 0)) == PLUS)
+    return r0rel_constant_p (XEXP (XEXP (op, 0), 0));
+
+  return false;
+}
+
 /* Return the name string for a supported unspec reloc offset.  */
 static const char *
 nios2_unspec_reloc_name (int unspec)
@@ -3048,7 +3108,13 @@ nios2_print_operand_address (FILE *file, machine_mode mode, rtx op)
           fprintf (file, ")(%s)", reg_names[GP_REGNO]);
           return;
         }
-
+      else if (r0rel_constant_p (op))
+        {
+          fprintf (file, "%%lo(");
+          output_addr_const (file, op);
+          fprintf (file, ")(r0)");
+          return;
+        }
       break;
 
     case PLUS:
@@ -4654,8 +4720,8 @@ nios2_cdx_narrow_form_p (rtx_insn *insn)
                || TARGET_BYPASS_CACHE)
              return false;
            addr = XEXP (mem, 0);
-           /* GP-based references are never narrow.  */
-           if (gprel_constant_p (addr))
+           /* GP-based and R0-based references are never narrow.  */
+           if (gprel_constant_p (addr) || r0rel_constant_p (addr))
                return false;
            /* %lo requires a 16-bit relocation and is never narrow.  */
            if (GET_CODE (addr) == LO_SUM)
@@ -4701,8 +4767,8 @@ nios2_cdx_narrow_form_p (rtx_insn *insn)
              || TARGET_BYPASS_CACHE)
            return false;
          addr = XEXP (mem, 0);
-         /* GP-based references are never narrow.  */
-         if (gprel_constant_p (addr))
+         /* GP-based and r0-based references are never narrow.  */
+         if (gprel_constant_p (addr) || r0rel_constant_p (addr))
            return false;
          /* %lo requires a 16-bit relocation and is never narrow.  */
          if (GET_CODE (addr) == LO_SUM)
index d08405e64b8795c11d8ad4cbd4cbb7ac68802d7b..a50dbee3fa78254facf0bd0b1446ca96066a402a 100644 (file)
@@ -589,4 +589,8 @@ Enable generation of R2 CDX instructions.
 
 mgprel-sec=
 Target RejectNegative Joined Var(nios2_gprel_sec) Init(NULL)
-Regular expression matching additional GP-addressible small-data section names.
+Regular expression matching additional GP-addressible section names.
+
+mr0rel-sec=
+Target RejectNegative Joined Var(nios2_r0rel_sec) Init(NULL)
+Regular expression matching section names for r0-relative addressing.
index d2001cac1997afce6bf9996cad1b9ecd8f11d1f8..2fc087a3042c0cc74ef5b116e17d7c391887e5e5 100644 (file)
@@ -948,7 +948,7 @@ Objective-C and Objective-C++ Dialects}.
 
 @emph{Nios II Options}
 @gccoptlist{-G @var{num}  -mgpopt=@var{option}  -mgpopt  -mno-gpopt @gol
--mgprel-sec=@var{regexp} @gol
+-mgprel-sec=@var{regexp} -mr0rel-sec=@var{regexp} @gol
 -mel  -meb @gol
 -mno-bypass-cache  -mbypass-cache @gol
 -mno-cache-volatile  -mcache-volatile @gol
@@ -21184,6 +21184,20 @@ This option does not affect the behavior of the @option{-G} option, and
 and the specified sections are in addition to the standard @code{.sdata} 
 and @code{.sbss} small-data sections that are recognized by @option{-mgpopt}.
 
+@item -mr0rel-sec=@var{regexp}
+@opindex mr0rel-sec
+This option specifies names of sections that can be accessed via a 
+16-bit offset from @code{r0}; that is, in the low 32K or high 32K 
+of the 32-bit address space.  It is most useful in conjunction with 
+@code{section} attributes on variable declarations 
+(@pxref{Common Variable Attributes}) and a custom linker script.  
+The @var{regexp} is a POSIX Extended Regular Expression.
+
+In contrast to the use of GP-relative addressing for small data, 
+zero-based addressing is never generated by default and there are no 
+conventional section names used in standard linker scripts for sections
+in the low or high areas of memory.
+
 @item -mel
 @itemx -meb
 @opindex mel
index f8d82499939ae737736b83e937486b41449f3f87..2f840a96f753c2d67e196ce7f4482a7aa7ca4508 100644 (file)
@@ -1,3 +1,7 @@
+2017-10-26  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * gcc.target/nios2/gpopt-r0rel-sec.c: New.
+
 2017-10-26  Sandra Loosemore  <sandra@codesourcery.com>
 
        * gcc.target/nios2/gpopt-gprel-sec.c: New.
diff --git a/gcc/testsuite/gcc.target/nios2/gpopt-r0rel-sec.c b/gcc/testsuite/gcc.target/nios2/gpopt-r0rel-sec.c
new file mode 100644 (file)
index 0000000..5fda9e9
--- /dev/null
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mgpopt=local -mr0rel-sec=\\.frog.+" } */
+
+extern int a __attribute__ ((section (".frog1")));
+static volatile int b __attribute__ ((section (".frog2"))) = 1;
+extern int c __attribute__ ((section (".data")));
+static volatile int d __attribute__ ((section (".data"))) = 2;
+
+extern int e;
+static volatile int f = 3;
+
+volatile int g __attribute__ ((weak)) = 4;
+
+extern int h[100];
+static int i[100];
+static int j[100] __attribute__ ((section (".sdata")));
+
+typedef int (*ftype) (int);
+extern int foo (int);
+
+extern int bar (int, int*, int*, int*, ftype);
+
+int baz (void)
+{
+  return bar (a + b + c + d + e + f + g, h, i, j, foo);
+}
+
+/* { dg-final { scan-assembler "%lo\\(a\\)\\(r0\\)" } } */
+/* { dg-final { scan-assembler "%lo\\(b\\)\\(r0\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(c\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(d\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(e\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(f\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(g\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(h\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(i\\)" } } */
+/* { dg-final { scan-assembler "%gprel\\(j\\)" } } */
+/* { dg-final { scan-assembler-not "%gprel\\(foo\\)" } } */