aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandra Loosemore <sandra@codesourcery.com>2015-07-14 22:34:23 +0000
committerSandra Loosemore <sandra@codesourcery.com>2015-07-14 22:34:23 +0000
commit5428c3e031b7449eaea9ad1192806cd4d50ea262 (patch)
treebf04fdbea43651a05a4d5427cd7eeafe6ceca391
parent6e192015c40f65d2e09fd35f5257a82f16afaafd (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@225792 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/nios2/constraints.md8
-rw-r--r--gcc/config/nios2/nios2.c24
-rw-r--r--gcc/config/nios2/nios2.h1
-rw-r--r--gcc/config/nios2/nios2.md8
-rw-r--r--gcc/config/nios2/predicates.md17
-rw-r--r--gcc/doc/md.texi4
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/gcc.target/nios2/nios2-ldxio.c52
-rw-r--r--gcc/testsuite/gcc.target/nios2/nios2-stxio.c10
-rw-r--r--gcc/testsuite/gcc.target/nios2/r2-io-range.c18
-rw-r--r--gcc/testsuite/gcc.target/nios2/r2-stio-1.c19
-rw-r--r--gcc/testsuite/gcc.target/nios2/r2-stio-2.c19
13 files changed, 201 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b6026ba64ec..80b38cdb51e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -2,6 +2,22 @@
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>
+
* config/nios2/nios2.opt (march, mbmx, mcdx): New options.
* config/nios2/nios2-opts.h (enum nios2_arch_type): New enum for
Nios II architecture level.
diff --git a/gcc/config/nios2/constraints.md b/gcc/config/nios2/constraints.md
index b67e87d3b3c..7c7afdfb115 100644
--- a/gcc/config/nios2/constraints.md
+++ b/gcc/config/nios2/constraints.md
@@ -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"))
diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c
index 7c97a02b521..93e0a869f32 100644
--- a/gcc/config/nios2/nios2.c
+++ b/gcc/config/nios2/nios2.c
@@ -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
diff --git a/gcc/config/nios2/nios2.h b/gcc/config/nios2/nios2.h
index c3c958a083d..58afaec69ce 100644
--- a/gcc/config/nios2/nios2.h
+++ b/gcc/config/nios2/nios2.h
@@ -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)
diff --git a/gcc/config/nios2/nios2.md b/gcc/config/nios2/nios2.md
index 70977802009..8cf2347e05c 100644
--- a/gcc/config/nios2/nios2.md
+++ b/gcc/config/nios2/nios2.md
@@ -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))]
""
diff --git a/gcc/config/nios2/predicates.md b/gcc/config/nios2/predicates.md
index 37cecf774f2..fa578035cca 100644
--- a/gcc/config/nios2/predicates.md
+++ b/gcc/config/nios2/predicates.md
@@ -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);
+})
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index e991286afcc..84c39a853e9 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -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,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 801e46285a9..6dd4feb719d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.target/nios2/nios2-ldxio.c b/gcc/testsuite/gcc.target/nios2/nios2-ldxio.c
new file mode 100644
index 00000000000..ac661a0e2a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nios2/nios2-ldxio.c
@@ -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);
+}
diff --git a/gcc/testsuite/gcc.target/nios2/nios2-stxio.c b/gcc/testsuite/gcc.target/nios2/nios2-stxio.c
index af079d641c7..0e675be3962 100644
--- a/gcc/testsuite/gcc.target/nios2/nios2-stxio.c
+++ b/gcc/testsuite/gcc.target/nios2/nios2-stxio.c
@@ -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);
}
+
diff --git a/gcc/testsuite/gcc.target/nios2/r2-io-range.c b/gcc/testsuite/gcc.target/nios2/r2-io-range.c
new file mode 100644
index 00000000000..2064ff6b0d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nios2/r2-io-range.c
@@ -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.*\\)" } } */
diff --git a/gcc/testsuite/gcc.target/nios2/r2-stio-1.c b/gcc/testsuite/gcc.target/nios2/r2-stio-1.c
new file mode 100644
index 00000000000..5aadd20d340
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nios2/r2-stio-1.c
@@ -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)" } } */
+
diff --git a/gcc/testsuite/gcc.target/nios2/r2-stio-2.c b/gcc/testsuite/gcc.target/nios2/r2-stio-2.c
new file mode 100644
index 00000000000..0a6de908d6e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nios2/r2-stio-2.c
@@ -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)" } } */
+