Commit 1cef1159 by Sandra Loosemore Committed by Sandra Loosemore

constraints.md ("S"): Match r0rel_constant_p too.

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
parent de10fca0
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.
(nios2_gprel_sec_regex): New.
(nios2_option_overide): Initialize it. Don't allow GP-relative
......@@ -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."
......
......@@ -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);
......
......@@ -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;
/* 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)
......
......@@ -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.
......@@ -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
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.
2017-10-26 Olga Makhotina <olga.makhotina@intel.com>
......
/* { 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\\)" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment