diff options
author | sandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-07-14 22:34:23 +0000 |
---|---|---|
committer | sandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-07-14 22:34:23 +0000 |
commit | 7eb60b4dda7cb3e5b67d4adbb7701b48d7076b67 (patch) | |
tree | bf04fdbea43651a05a4d5427cd7eeafe6ceca391 /gcc/config/nios2 | |
parent | 9515cb26b8b1c09770cce6e2f57eb3273d4a1fd7 (diff) | |
download | gcc-7eb60b4dda7cb3e5b67d4adbb7701b48d7076b67.tar.gz |
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: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225792 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/nios2')
-rw-r--r-- | gcc/config/nios2/constraints.md | 8 | ||||
-rw-r--r-- | gcc/config/nios2/nios2.c | 24 | ||||
-rw-r--r-- | gcc/config/nios2/nios2.h | 1 | ||||
-rw-r--r-- | gcc/config/nios2/nios2.md | 8 | ||||
-rw-r--r-- | gcc/config/nios2/predicates.md | 17 |
5 files changed, 53 insertions, 5 deletions
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); +}) |