nios2.h (SMALL_INT12): New macro.

2015-07-14  Sandra Loosemore  <sandra@codesourcery.com>
	    Cesar Philippidis  <cesar@codesourcery.com>
	    Chung-Lin Tang  <cltang@codesourcery.com>

	gcc/
	* config/nios2/nios2.h (SMALL_INT12): New macro.
	* config/nios2/nios2.c (nios2_valid_addr_offset_p): New function.
	(nios2_valid_addr_expr_p): Use it.
	(nios2_symbol_ref_in_small_data_p): Disallow GP-relative addressing
	with implicit "io" instructions on R2.
	* config/nios2/constraints.md (w): New constraint.
	* config/nios2/predicates.md (ldstio_memory_operand): New.
	* config/nios2/nios2.md (ld<bhw_uns>io, ld<bh>io): Update memory
	operand predicate and constraint.
	(ld<bh>io_signed, st<bhw>io>): Likewise.
	* doc/md.texi (Machine Constraints): Document w constraint.

	gcc/testsuite/
	* gcc.target/nios2/r2-io-range.c: New.
	* gcc.target/nios2/r2-stio-1.c: New.
	* gcc.target/nios2/r2-stio-2.c: New.
	* gcc.target/nios2/nios2-ldxio.c: New.
	* gcc.target/nios2/nios2-stxio.c: Change to assemble test instead
	of just compile.  Add more tests.

Co-Authored-By: Cesar Philippidis <cesar@codesourcery.com>
Co-Authored-By: Chung-Lin Tang <cltang@codesourcery.com>

From-SVN: r225792
This commit is contained in:
Sandra Loosemore 2015-07-14 18:34:23 -04:00 committed by Sandra Loosemore
parent 77c50d73f6
commit 42e6ab74b6
13 changed files with 201 additions and 6 deletions

View file

@ -1,3 +1,19 @@
2015-07-14 Sandra Loosemore <sandra@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
Chung-Lin Tang <cltang@codesourcery.com>
* config/nios2/nios2.h (SMALL_INT12): New macro.
* config/nios2/nios2.c (nios2_valid_addr_offset_p): New function.
(nios2_valid_addr_expr_p): Use it.
(nios2_symbol_ref_in_small_data_p): Disallow GP-relative addressing
with implicit "io" instructions on R2.
* config/nios2/constraints.md (w): New constraint.
* config/nios2/predicates.md (ldstio_memory_operand): New.
* config/nios2/nios2.md (ld<bhw_uns>io, ld<bh>io): Update memory
operand predicate and constraint.
(ld<bh>io_signed, st<bhw>io>): Likewise.
* doc/md.texi (Machine Constraints): Document w constraint.
2015-07-14 Sandra Loosemore <sandra@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
Chung-Lin Tang <cltang@codesourcery.com>

View file

@ -28,6 +28,10 @@
;; N: 0 to 255 (for custom instruction numbers)
;; O: 0 to 31 (for control register numbers)
;;
;; We use the following constraint letters for memory constraints
;;
;; w: memory operands for load/store IO and cache instructions
;;
;; We use the following built-in register classes:
;;
;; r: general purpose register (r0..r31)
@ -89,3 +93,7 @@
(define_constraint "T"
"A constant unspec offset representing a relocation."
(match_test "nios2_unspec_reloc_p (op)"))
(define_memory_constraint "w"
"A memory operand suitable for load/store IO and cache instructions."
(match_operand 0 "ldstio_memory_operand"))

View file

@ -1627,6 +1627,21 @@ nios2_regno_ok_for_base_p (int regno, bool strict_p)
|| regno == ARG_POINTER_REGNUM);
}
/* Return true if OFFSET is permitted in a load/store address expression.
Normally any 16-bit value is permitted, but on R2 if we may be emitting
the IO forms of these instructions we must restrict the offset to fit
in a 12-bit field instead. */
static bool
nios2_valid_addr_offset_p (rtx offset)
{
return (CONST_INT_P (offset)
&& ((TARGET_ARCH_R2 && (TARGET_BYPASS_CACHE
|| TARGET_BYPASS_CACHE_VOLATILE))
? SMALL_INT12 (INTVAL (offset))
: SMALL_INT (INTVAL (offset))));
}
/* Return true if the address expression formed by BASE + OFFSET is
valid. */
static bool
@ -1637,7 +1652,7 @@ nios2_valid_addr_expr_p (rtx base, rtx offset, bool strict_p)
return (REG_P (base)
&& nios2_regno_ok_for_base_p (REGNO (base), strict_p)
&& (offset == NULL_RTX
|| const_arith_operand (offset, Pmode)
|| nios2_valid_addr_offset_p (offset)
|| nios2_unspec_reloc_p (offset)));
}
@ -1739,6 +1754,13 @@ nios2_symbol_ref_in_small_data_p (rtx sym)
if (SYMBOL_REF_TLS_MODEL (sym) != 0)
return false;
/* On Nios II R2, there is no GP-relative relocation that can be
used with "io" instructions. So, if we are implicitly generating
those instructions, we cannot emit GP-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 small data section
via an attribute, generate gp-relative addressing even if the symbol
is external, weak, or larger than we'd automatically put in the

View file

@ -216,6 +216,7 @@ enum reg_class
/* Tests for various kinds of constants used in the Nios II port. */
#define SMALL_INT(X) ((unsigned HOST_WIDE_INT)(X) + 0x8000 < 0x10000)
#define SMALL_INT12(X) ((unsigned HOST_WIDE_INT)(X) + 0x800 < 0x1000)
#define SMALL_INT_UNSIGNED(X) ((X) >= 0 && (X) < 0x10000)
#define UPPER16_INT(X) (((X) & 0xffff) == 0)
#define SHIFT_INT(X) ((X) >= 0 && (X) <= 31)

View file

@ -221,14 +221,14 @@
(define_insn "ld<bhw_uns>io"
[(set (match_operand:BHW 0 "register_operand" "=r")
(unspec_volatile:BHW
[(match_operand:BHW 1 "memory_operand" "m")] UNSPECV_LDXIO))]
[(match_operand:BHW 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO))]
""
"ld<bhw_uns>io\\t%0, %1"
[(set_attr "type" "ld")])
(define_expand "ld<bh>io"
[(set (match_operand:BH 0 "register_operand" "=r")
(match_operand:BH 1 "memory_operand" "m"))]
(match_operand:BH 1 "ldstio_memory_operand" "w"))]
""
{
rtx tmp = gen_reg_rtx (SImode);
@ -241,13 +241,13 @@
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI
(unspec_volatile:BH
[(match_operand:BH 1 "memory_operand" "m")] UNSPECV_LDXIO)))]
[(match_operand:BH 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO)))]
""
"ld<bh>io\\t%0, %1"
[(set_attr "type" "ld")])
(define_insn "st<bhw>io"
[(set (match_operand:BHW 0 "memory_operand" "=m")
[(set (match_operand:BHW 0 "ldstio_memory_operand" "=w")
(unspec_volatile:BHW
[(match_operand:BHW 1 "reg_or_0_operand" "rM")] UNSPECV_STXIO))]
""

View file

@ -83,3 +83,20 @@
&XEXP (op, 0), &XEXP (op, 1),
false));
})
(define_predicate "ldstio_memory_operand"
(match_code "mem")
{
if (TARGET_ARCH_R2)
{
rtx addr = XEXP (op, 0);
if (REG_P (addr))
return true;
else if (GET_CODE (addr) == PLUS)
return (REG_P (XEXP (addr, 0))
&& CONST_INT_P (XEXP (addr, 1))
&& SMALL_INT12 (INTVAL (XEXP (addr, 1))));
return false;
}
return memory_operand (op, mode);
})

View file

@ -2996,6 +2996,10 @@ Matches immediates which are addresses in the small
data section and therefore can be added to @code{gp}
as a 16-bit immediate to re-create their 32-bit value.
@item w
A memory operand suitable for load/store IO and cache
instructions.
@ifset INTERNALS
@item T
A @code{const} wrapped @code{UNSPEC} expression,

View file

@ -1,3 +1,14 @@
2015-07-14 Sandra Loosemore <sandra@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
Chung-Lin Tang <cltang@codesourcery.com>
* gcc.target/nios2/r2-io-range.c: New.
* gcc.target/nios2/r2-stio-1.c: New.
* gcc.target/nios2/r2-stio-2.c: New.
* gcc.target/nios2/nios2-ldxio.c: New.
* gcc.target/nios2/nios2-stxio.c: Change to assemble test instead
of just compile. Add more tests.
2015-07-14 Steven G. Kargl <kargl@gcc.gnu.org>
gfortran.dg/pr66864.f90: New test.

View file

@ -0,0 +1,52 @@
/* { dg-do assemble } */
/* { dg-options "-O" } */
void test_ldbio (unsigned char* p1, unsigned char* p2)
{
__builtin_ldbio (p1);
__builtin_ldbio (p2);
__builtin_ldbio (p2 + 1);
__builtin_ldbio (p2 + 2);
__builtin_ldbio (p2 + 2047);
__builtin_ldbio (p2 + 2048);
}
void test_ldbuio (unsigned char* p1, unsigned char* p2)
{
__builtin_ldbuio (p1);
__builtin_ldbuio (p2);
__builtin_ldbuio (p2 + 1);
__builtin_ldbuio (p2 + 2);
__builtin_ldbuio (p2 + 2047);
__builtin_ldbuio (p2 + 2048);
}
void test_ldhio (unsigned short* p1, unsigned short* p2)
{
__builtin_ldhio (p1);
__builtin_ldhio (p2);
__builtin_ldhio (p2 + 1);
__builtin_ldhio (p2 + 2);
__builtin_ldhio (p2 + 1023);
__builtin_ldhio (p2 + 1024);
}
void test_ldhuio (unsigned short* p1, unsigned short* p2)
{
__builtin_ldhuio (p1);
__builtin_ldhuio (p2);
__builtin_ldhuio (p2 + 1);
__builtin_ldhuio (p2 + 2);
__builtin_ldhuio (p2 + 1023);
__builtin_ldhuio (p2 + 1024);
}
void test_ldwio (unsigned int* p1, unsigned int* p2)
{
__builtin_ldwio (p1);
__builtin_ldwio (p2);
__builtin_ldwio (p2 + 1);
__builtin_ldwio (p2 + 2);
__builtin_ldwio (p2 + 511);
__builtin_ldwio (p2 + 512);
}

View file

@ -1,4 +1,5 @@
/* { dg-do compile } */
/* { dg-do assemble } */
/* { dg-options "-O" } */
void test_stbio (unsigned char* p1, unsigned char* p2)
{
@ -6,6 +7,8 @@ void test_stbio (unsigned char* p1, unsigned char* p2)
__builtin_stbio (p2, 0);
__builtin_stbio (p2 + 1, 0x80);
__builtin_stbio (p2 + 2, 0x7f);
__builtin_stbio (p2 + 2047, 0x80);
__builtin_stbio (p2 + 2048, 0x7f);
}
void test_sthio (unsigned short* p1, unsigned short* p2)
@ -14,6 +17,8 @@ void test_sthio (unsigned short* p1, unsigned short* p2)
__builtin_sthio (p2, 0);
__builtin_sthio (p2 + 1, 0x8000);
__builtin_sthio (p2 + 2, 0x7fff);
__builtin_sthio (p2 + 1023, 0x8000);
__builtin_sthio (p2 + 1024, 0x7fff);
}
void test_stwio (unsigned int* p1, unsigned int* p2)
@ -22,4 +27,7 @@ void test_stwio (unsigned int* p1, unsigned int* p2)
__builtin_stwio (p2, 0);
__builtin_stwio (p2 + 1, 0x80000000);
__builtin_stwio (p2 + 2, 0x7fffffff);
__builtin_stwio (p2 + 511, 5);
__builtin_stwio (p2 + 512, 5);
}

View file

@ -0,0 +1,18 @@
/* { dg-do compile } */
/* { dg-options "-O2 -march=r2 -mbypass-cache" } */
/* Check that the compiler is aware of the reduced offset range for ldio/stio
instructions in the Nios II R2 encoding. */
unsigned int too_big (unsigned int *p)
{
return *(p + 0x400);
}
unsigned int small_enough (unsigned int *p)
{
return *(p + 0x100);
}
/* { dg-final { scan-assembler-not "\tldwio\t.*, 4096\\(r.*\\)" } } */
/* { dg-final { scan-assembler "\tldwio\t.*, 1024\\(r.*\\)" } } */

View file

@ -0,0 +1,19 @@
/* { dg-do compile } */
/* { dg-options "-O -mgpopt -march=r2" } */
/* The ldio/stio builtins must not use GP-relative addresses for
small data objects in R2. This is because the address offset field
has been reduced to 12 bits in R2, and %gprel is a 16-bit relocation. */
extern volatile unsigned int frob;
volatile unsigned int frob = 0;
void foo (unsigned int val)
{
__builtin_stwio (&frob, val);
}
/* { dg-final { scan-assembler "stwio\\t" } } */
/* { dg-final { scan-assembler-not "stwio\\t.*%gprel(frob)" } } */

View file

@ -0,0 +1,19 @@
/* { dg-do compile } */
/* { dg-options "-O -mgpopt -march=r2 -mbypass-cache" } */
/* Implicit ldio/stio operations must not use GP-relative addresses for
small data objects in R2. This is because the address offset field
has been reduced to 12 bits in R2, and %gprel is a 16-bit relocation. */
extern volatile unsigned int frob;
volatile unsigned int frob = 0;
void foo (unsigned int val)
{
frob = val;
}
/* { dg-final { scan-assembler "stwio\\t" } } */
/* { dg-final { scan-assembler-not "stwio\\t.*%gprel(frob)" } } */