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:
parent
77c50d73f6
commit
42e6ab74b6
13 changed files with 201 additions and 6 deletions
|
@ -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>
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))]
|
||||
""
|
||||
|
|
|
@ -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);
|
||||
})
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
52
gcc/testsuite/gcc.target/nios2/nios2-ldxio.c
Normal file
52
gcc/testsuite/gcc.target/nios2/nios2-ldxio.c
Normal 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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
18
gcc/testsuite/gcc.target/nios2/r2-io-range.c
Normal file
18
gcc/testsuite/gcc.target/nios2/r2-io-range.c
Normal 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.*\\)" } } */
|
19
gcc/testsuite/gcc.target/nios2/r2-stio-1.c
Normal file
19
gcc/testsuite/gcc.target/nios2/r2-stio-1.c
Normal 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)" } } */
|
||||
|
19
gcc/testsuite/gcc.target/nios2/r2-stio-2.c
Normal file
19
gcc/testsuite/gcc.target/nios2/r2-stio-2.c
Normal 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)" } } */
|
||||
|
Loading…
Add table
Reference in a new issue