From 1cef1159dbf7af419d9cd2c75fadcd1eb2fa0ab3 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Thu, 26 Oct 2017 16:52:15 -0400 Subject: constraints.md ("S"): Match r0rel_constant_p too. 2017-10-26 Sandra Loosemore 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 | 20 +++++ gcc/config/nios2/constraints.md | 4 +- gcc/config/nios2/nios2-protos.h | 1 + gcc/config/nios2/nios2.c | 94 ++++++++++++++++++++---- gcc/config/nios2/nios2.opt | 6 +- gcc/doc/invoke.texi | 16 +++- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.target/nios2/gpopt-r0rel-sec.c | 38 ++++++++++ 8 files changed, 165 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gcc.target/nios2/gpopt-r0rel-sec.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ee9da2..558ec9b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,25 @@ 2017-10-26 Sandra Loosemore + * 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 + * config/nios2/nios2.c: Include xregex.h. (nios2_gprel_sec_regex): New. (nios2_option_overide): Initialize it. Don't allow GP-relative diff --git a/gcc/config/nios2/constraints.md b/gcc/config/nios2/constraints.md index c6c53926..51f71cf 100644 --- a/gcc/config/nios2/constraints.md +++ b/gcc/config/nios2/constraints.md @@ -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." diff --git a/gcc/config/nios2/nios2-protos.h b/gcc/config/nios2/nios2-protos.h index 6df65bb..84d450b 100644 --- a/gcc/config/nios2/nios2-protos.h +++ b/gcc/config/nios2/nios2-protos.h @@ -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); diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c index 3aade7b..cdd5e9a 100644 --- a/gcc/config/nios2/nios2.c +++ b/gcc/config/nios2/nios2.c @@ -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) diff --git a/gcc/config/nios2/nios2.opt b/gcc/config/nios2/nios2.opt index d08405e..a50dbee 100644 --- a/gcc/config/nios2/nios2.opt +++ b/gcc/config/nios2/nios2.opt @@ -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. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index d2001ca..2fc087a 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f8d8249..2f840a9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2017-10-26 Sandra Loosemore + * gcc.target/nios2/gpopt-r0rel-sec.c: New. + +2017-10-26 Sandra Loosemore + * gcc.target/nios2/gpopt-gprel-sec.c: New. 2017-10-26 Olga Makhotina 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 index 0000000..5fda9e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/nios2/gpopt-r0rel-sec.c @@ -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\\)" } } */ -- cgit v1.1