constraints.md (U, v): New constraints.
authorSandra Loosemore <sandra@codesourcery.com>
Tue, 14 Jul 2015 23:43:48 +0000 (19:43 -0400)
committerSandra Loosemore <sandra@gcc.gnu.org>
Tue, 14 Jul 2015 23:43:48 +0000 (19:43 -0400)
2015-07-14  Sandra Loosemore  <sandra@codesourcery.com>
    Cesar Philippidis  <cesar@codesourcery.com>
    Chung-Lin Tang  <cltang@codesourcery.com>

gcc/
* config/nios2/constraints.md (U, v): New constraints.
* config/nios2/predicates.md (rdprs_dcache_operand): New.
(ldstex_memory_operand): New.
* config/nios2/sync.md: New file.
* config/nios2/nios2.md (unspecv): Add new builtin function
UNSPECV codes.
(rdprs, flushd, flushda, wrpie, eni): New patterns.
(top-level): Include sync.md.
* config/nios2/nios2.c (N2_FTYPES): Add function types for
new builtins.
(N2_BUILTINS): Add arch field setting, add new builtins.
(enum nios2_builtin_code,nios2_builtins): Update N2_BUILTIN_DEF
for arch field.
(nios2_expand_ldst_builtin): Rename from nios2_expand_ldstio_builtin.
Also handle ldex/stex/ldsex/stsex builtins.
(nios2_expand_rdprs_builtin): New function.
(nios2_expand_cache_builtin): New function.
(nios2_expand_wrpie_builtin): New function.
(nios2_expand_eni_builtin): New function.
(nios2_expand_builtin): Add arch field handling and new builtin
        cases.
* doc/extend.texi (Altera Nios II Built-in Functions): Document
new builtins.
* doc/md.texi (Machine Constraints): Document U and v constraints.

gcc/testsuite/
* gcc.target/nios2/nios2-flushd.c: New.
* gcc.target/nios2/nios2-rdprs.c: New.
* gcc.target/nios2/r2-atomic.c: New.
* gcc.target/nios2/r2-eni.c: New.
* gcc.target/nios2/r2-wrpie.c: New.

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

14 files changed:
gcc/ChangeLog
gcc/config/nios2/constraints.md
gcc/config/nios2/nios2.c
gcc/config/nios2/nios2.md
gcc/config/nios2/predicates.md
gcc/config/nios2/sync.md [new file with mode: 0644]
gcc/doc/extend.texi
gcc/doc/md.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/nios2/nios2-flushd.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nios2/nios2-rdprs.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nios2/r2-atomic.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nios2/r2-eni.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nios2/r2-wrpie.c [new file with mode: 0644]

index 43d9b3c1f9ec50ca2e896f84c4e6c907a80d2443..1e7fbabac88e485b0d075ece0230734680a900e3 100644 (file)
@@ -1,3 +1,32 @@
+2015-07-14  Sandra Loosemore  <sandra@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+           Chung-Lin Tang  <cltang@codesourcery.com>
+
+       * config/nios2/constraints.md (U, v): New constraints.
+       * config/nios2/predicates.md (rdprs_dcache_operand): New.
+       (ldstex_memory_operand): New.
+       * config/nios2/sync.md: New file.
+       * config/nios2/nios2.md (unspecv): Add new builtin function
+       UNSPECV codes.
+       (rdprs, flushd, flushda, wrpie, eni): New patterns.
+       (top-level): Include sync.md.
+       * config/nios2/nios2.c (N2_FTYPES): Add function types for
+       new builtins.
+       (N2_BUILTINS): Add arch field setting, add new builtins.
+       (enum nios2_builtin_code,nios2_builtins): Update N2_BUILTIN_DEF
+       for arch field.
+       (nios2_expand_ldst_builtin): Rename from nios2_expand_ldstio_builtin.
+       Also handle ldex/stex/ldsex/stsex builtins.
+       (nios2_expand_rdprs_builtin): New function.
+       (nios2_expand_cache_builtin): New function.
+       (nios2_expand_wrpie_builtin): New function.
+       (nios2_expand_eni_builtin): New function.
+       (nios2_expand_builtin): Add arch field handling and new builtin 
+        cases.
+       * doc/extend.texi (Altera Nios II Built-in Functions): Document
+       new builtins.
+       * doc/md.texi (Machine Constraints): Document U and v constraints.
+
 2015-07-14  Sandra Loosemore  <sandra@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
            Chung-Lin Tang  <cltang@codesourcery.com>
index 0ec817fd77182b27e3f2d48102b09ee8b3166563..6f7afa4358fe944956e25c76a50b466e874ef772 100644 (file)
 ;;  M: 0
 ;;  N: 0 to 255 (for custom instruction numbers)
 ;;  O: 0 to 31 (for control register numbers)
+;;  U: -32768 to 32767 under R1, -2048 to 2047 under R2
 ;;
 ;; We use the following constraint letters for memory constraints
 ;;
+;;  v: memory operands for R2 load/store exclusive instructions
 ;;  w: memory operands for load/store IO and cache instructions
 ;;
 ;; We use the following built-in register classes:
   "A constant unspec offset representing a relocation."
   (match_test "nios2_unspec_reloc_p (op)"))
 
+(define_constraint "U"
+  "A 12-bit or 16-bit constant (for RDPRS and DCACHE)."
+  (and (match_code "const_int")
+       (if_then_else (match_test "TARGET_ARCH_R2")
+                     (match_test "SMALL_INT12 (ival)")
+                     (match_test "SMALL_INT (ival)"))))
+
+(define_memory_constraint "v"
+  "A memory operand suitable for R2 load/store exclusive instructions."
+  (match_operand 0 "ldstex_memory_operand"))
+
 (define_memory_constraint "w"
   "A memory operand suitable for load/store IO and cache instructions."
   (match_operand 0 "ldstio_memory_operand"))
index 2d7c4a2169fc5911c28b5e7cd4ea9966105bebd3..a780c512060dd8f0d7ff47fe7cbc242416d16d63 100644 (file)
@@ -135,12 +135,16 @@ static bool custom_code_conflict = false;
   N2_FTYPE(2, (SI, SF))                                \
   N2_FTYPE(3, (SI, SF, SF))                    \
   N2_FTYPE(2, (SI, SI))                                \
+  N2_FTYPE(3, (SI, SI, SI))                    \
+  N2_FTYPE(3, (SI, VPTR, SI))                  \
   N2_FTYPE(2, (UI, CVPTR))                     \
   N2_FTYPE(2, (UI, DF))                                \
   N2_FTYPE(2, (UI, SF))                                \
   N2_FTYPE(2, (VOID, DF))                      \
   N2_FTYPE(2, (VOID, SF))                      \
+  N2_FTYPE(2, (VOID, SI))                      \
   N2_FTYPE(3, (VOID, SI, SI))                  \
+  N2_FTYPE(2, (VOID, VPTR))                    \
   N2_FTYPE(3, (VOID, VPTR, SI))
 
 #define N2_FTYPE_OP1(R)         N2_FTYPE_ ## R ## _VOID
@@ -3266,33 +3270,43 @@ nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target)
 struct nios2_builtin_desc
 {
   enum insn_code icode;
+  enum nios2_arch_type arch;
   enum nios2_ftcode ftype;
   const char *name;
 };
 
 #define N2_BUILTINS                                    \
-  N2_BUILTIN_DEF (sync,   N2_FTYPE_VOID_VOID)          \
-  N2_BUILTIN_DEF (ldbio,  N2_FTYPE_SI_CVPTR)           \
-  N2_BUILTIN_DEF (ldbuio, N2_FTYPE_UI_CVPTR)           \
-  N2_BUILTIN_DEF (ldhio,  N2_FTYPE_SI_CVPTR)           \
-  N2_BUILTIN_DEF (ldhuio, N2_FTYPE_UI_CVPTR)           \
-  N2_BUILTIN_DEF (ldwio,  N2_FTYPE_SI_CVPTR)           \
-  N2_BUILTIN_DEF (stbio,  N2_FTYPE_VOID_VPTR_SI)       \
-  N2_BUILTIN_DEF (sthio,  N2_FTYPE_VOID_VPTR_SI)       \
-  N2_BUILTIN_DEF (stwio,  N2_FTYPE_VOID_VPTR_SI)       \
-  N2_BUILTIN_DEF (rdctl,  N2_FTYPE_SI_SI)              \
-  N2_BUILTIN_DEF (wrctl,  N2_FTYPE_VOID_SI_SI)
+  N2_BUILTIN_DEF (sync,    R1, N2_FTYPE_VOID_VOID)     \
+  N2_BUILTIN_DEF (ldbio,   R1, N2_FTYPE_SI_CVPTR)      \
+  N2_BUILTIN_DEF (ldbuio,  R1, N2_FTYPE_UI_CVPTR)      \
+  N2_BUILTIN_DEF (ldhio,   R1, N2_FTYPE_SI_CVPTR)      \
+  N2_BUILTIN_DEF (ldhuio,  R1, N2_FTYPE_UI_CVPTR)      \
+  N2_BUILTIN_DEF (ldwio,   R1, N2_FTYPE_SI_CVPTR)      \
+  N2_BUILTIN_DEF (stbio,   R1, N2_FTYPE_VOID_VPTR_SI)  \
+  N2_BUILTIN_DEF (sthio,   R1, N2_FTYPE_VOID_VPTR_SI)  \
+  N2_BUILTIN_DEF (stwio,   R1, N2_FTYPE_VOID_VPTR_SI)  \
+  N2_BUILTIN_DEF (rdctl,   R1, N2_FTYPE_SI_SI)         \
+  N2_BUILTIN_DEF (wrctl,   R1, N2_FTYPE_VOID_SI_SI)    \
+  N2_BUILTIN_DEF (rdprs,   R1, N2_FTYPE_SI_SI_SI)      \
+  N2_BUILTIN_DEF (flushd,  R1, N2_FTYPE_VOID_VPTR)     \
+  N2_BUILTIN_DEF (flushda, R1, N2_FTYPE_VOID_VPTR)     \
+  N2_BUILTIN_DEF (wrpie,   R2, N2_FTYPE_SI_SI)         \
+  N2_BUILTIN_DEF (eni,     R2, N2_FTYPE_VOID_SI)       \
+  N2_BUILTIN_DEF (ldex,    R2, N2_FTYPE_SI_CVPTR)      \
+  N2_BUILTIN_DEF (ldsex,   R2, N2_FTYPE_SI_CVPTR)      \
+  N2_BUILTIN_DEF (stex,    R2, N2_FTYPE_SI_VPTR_SI)    \
+  N2_BUILTIN_DEF (stsex,   R2, N2_FTYPE_SI_VPTR_SI)
 
 enum nios2_builtin_code {
-#define N2_BUILTIN_DEF(name, ftype) NIOS2_BUILTIN_ ## name,
+#define N2_BUILTIN_DEF(name, arch, ftype) NIOS2_BUILTIN_ ## name,
   N2_BUILTINS
 #undef N2_BUILTIN_DEF
   NUM_FIXED_NIOS2_BUILTINS
 };
 
 static const struct nios2_builtin_desc nios2_builtins[] = {
-#define N2_BUILTIN_DEF(name, ftype)                    \
-  { CODE_FOR_ ## name, ftype, "__builtin_" #name },
+#define N2_BUILTIN_DEF(name, arch, ftype)              \
+  { CODE_FOR_ ## name, ARCH_ ## arch, ftype, "__builtin_" #name },
   N2_BUILTINS
 #undef N2_BUILTIN_DEF
 };
@@ -3373,10 +3387,11 @@ nios2_expand_builtin_insn (const struct nios2_builtin_desc *d, int n,
     } 
 }
 
-/* Expand ldio/stio form load-store instruction builtins.  */
+/* Expand ldio/stio and ldex/ldsex/stex/stsex form load-store
+   instruction builtins.  */
 static rtx
-nios2_expand_ldstio_builtin (tree exp, rtx target,
-                            const struct nios2_builtin_desc *d)
+nios2_expand_ldst_builtin (tree exp, rtx target,
+                          const struct nios2_builtin_desc *d)
 {
   bool has_target_p;
   rtx addr, mem, val;
@@ -3388,14 +3403,21 @@ nios2_expand_ldstio_builtin (tree exp, rtx target,
 
   if (insn_data[d->icode].operand[0].allows_mem)
     {
-      /* stxio.  */
+      /* stxio/stex/stsex.  */
       val = expand_normal (CALL_EXPR_ARG (exp, 1));
       if (CONST_INT_P (val))
        val = force_reg (mode, gen_int_mode (INTVAL (val), mode));
       val = simplify_gen_subreg (mode, val, GET_MODE (val), 0);
       create_output_operand (&ops[0], mem, mode);
       create_input_operand (&ops[1], val, mode);
-      has_target_p = false;
+      if (insn_data[d->icode].n_operands == 3)
+       {
+         /* stex/stsex status value, returned as result of function.  */
+         create_output_operand (&ops[2], target, mode);
+         has_target_p = true;
+       }
+      else
+       has_target_p = false;
     }
   else
     {
@@ -3404,7 +3426,8 @@ nios2_expand_ldstio_builtin (tree exp, rtx target,
       create_input_operand (&ops[1], mem, mode);
       has_target_p = true;
     }
-  return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
+  return nios2_expand_builtin_insn (d, insn_data[d->icode].n_operands, ops,
+                                   has_target_p);
 }
 
 /* Expand rdctl/wrctl builtins.  */
@@ -3436,6 +3459,81 @@ nios2_expand_rdwrctl_builtin (tree exp, rtx target,
   return nios2_expand_builtin_insn (d, 2, ops, has_target_p);
 }
 
+static rtx
+nios2_expand_rdprs_builtin (tree exp, rtx target,
+                           const struct nios2_builtin_desc *d)
+{
+  rtx reg = expand_normal (CALL_EXPR_ARG (exp, 0));
+  rtx imm = expand_normal (CALL_EXPR_ARG (exp, 1));
+  struct expand_operand ops[MAX_RECOG_OPERANDS];
+
+  if (!rdwrctl_operand (reg, VOIDmode))
+    {
+      error ("Register number must be in range 0-31 for %s",
+            d->name);
+      return gen_reg_rtx (SImode);
+    }
+
+  if (!rdprs_dcache_operand (imm, VOIDmode))
+    {
+      error ("The immediate value must fit into a %d-bit integer for %s",
+            (TARGET_ARCH_R2) ? 12 : 16, d->name);
+      return gen_reg_rtx (SImode);
+    }
+
+  create_output_operand (&ops[0], target, SImode);
+  create_input_operand (&ops[1], reg, SImode);
+  create_integer_operand (&ops[2], INTVAL (imm));
+
+  return nios2_expand_builtin_insn (d, 3, ops, true);
+}
+
+static rtx
+nios2_expand_cache_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
+                           const struct nios2_builtin_desc *d)
+{
+  rtx mem, addr;
+  struct expand_operand ops[MAX_RECOG_OPERANDS];
+
+  addr = expand_normal (CALL_EXPR_ARG (exp, 0));
+  mem = gen_rtx_MEM (SImode, addr);
+
+  create_input_operand (&ops[0], mem, SImode);
+  return nios2_expand_builtin_insn (d, 1, ops, false);
+}
+
+static rtx
+nios2_expand_wrpie_builtin (tree exp, rtx target,
+                           const struct nios2_builtin_desc *d)
+{
+  rtx val;
+  struct expand_operand ops[MAX_RECOG_OPERANDS];
+
+  val = expand_normal (CALL_EXPR_ARG (exp, 0));
+  create_input_operand (&ops[1], val, SImode);
+  create_output_operand (&ops[0], target, SImode);
+  return nios2_expand_builtin_insn (d, 2, ops, true);
+}
+
+static rtx
+nios2_expand_eni_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
+                           const struct nios2_builtin_desc *d)
+{
+  rtx imm = expand_normal (CALL_EXPR_ARG (exp, 0));
+  struct expand_operand ops[MAX_RECOG_OPERANDS];
+
+  if (INTVAL (imm) != 0 && INTVAL (imm) != 1)
+    {
+      error ("The ENI instruction operand must be either 0 or 1");
+      return const0_rtx;      
+    }
+  create_integer_operand (&ops[0], INTVAL (imm));
+  return nios2_expand_builtin_insn (d, 1, ops, false);
+}
+
 /* Implement TARGET_EXPAND_BUILTIN.  Expand an expression EXP that calls
    a built-in function, with result going to TARGET if that's convenient
    (and in mode MODE if that's convenient).
@@ -3454,6 +3552,14 @@ nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
     {
       const struct nios2_builtin_desc *d = &nios2_builtins[fcode];
 
+      if (d->arch > nios2_arch_option)
+       {
+         error ("Builtin function %s requires Nios II R%d",
+                d->name, (int) d->arch);
+         /* Given it is invalid, just generate a normal call.  */
+         return expand_call (exp, target, ignore);
+       }
+
       switch (fcode)
        {
        case NIOS2_BUILTIN_sync:
@@ -3468,12 +3574,29 @@ nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
        case NIOS2_BUILTIN_stbio:
        case NIOS2_BUILTIN_sthio:
        case NIOS2_BUILTIN_stwio:
-         return nios2_expand_ldstio_builtin (exp, target, d);
+       case NIOS2_BUILTIN_ldex:
+       case NIOS2_BUILTIN_ldsex:
+       case NIOS2_BUILTIN_stex:
+       case NIOS2_BUILTIN_stsex:
+         return nios2_expand_ldst_builtin (exp, target, d);
 
        case NIOS2_BUILTIN_rdctl:
        case NIOS2_BUILTIN_wrctl:
          return nios2_expand_rdwrctl_builtin (exp, target, d);
 
+       case NIOS2_BUILTIN_rdprs:
+         return nios2_expand_rdprs_builtin (exp, target, d);
+
+       case NIOS2_BUILTIN_flushd:
+       case NIOS2_BUILTIN_flushda:
+         return nios2_expand_cache_builtin (exp, target, d);
+
+       case NIOS2_BUILTIN_wrpie:
+         return nios2_expand_wrpie_builtin (exp, target, d);
+
+       case NIOS2_BUILTIN_eni:
+         return nios2_expand_eni_builtin (exp, target, d);
+
        default:
          gcc_unreachable ();
        }
index 23f236d85cbe5aaccfadcfe620727653594fbee7..88e689b00bf74aacc16727b2826a3fb4448af174 100644 (file)
   UNSPECV_CUSTOM_XNXX
   UNSPECV_LDXIO
   UNSPECV_STXIO
+  UNSPECV_RDPRS
+  UNSPECV_FLUSHD
+  UNSPECV_FLUSHDA
+  UNSPECV_WRPIE
+  UNSPECV_ENI
+  UNSPECV_LDEX
+  UNSPECV_LDSEX
+  UNSPECV_STEX
+  UNSPECV_STSEX
 ])
 
 (define_c_enum "unspec" [
   "wrctl\\tctl%0, %z1"
   [(set_attr "type" "control")])
 
+(define_insn "rdprs"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")
+                             (match_operand:SI 2 "arith_operand"   "U")]
+         UNSPECV_RDPRS))]
+  ""
+  "rdprs\\t%0, %1, %2"
+  [(set_attr "type" "control")])
+
+;; Cache Instructions
+
+(define_insn "flushd"
+  [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
+                       UNSPECV_FLUSHD)]
+  ""
+  "flushd\\t%0"
+  [(set_attr "type" "control")])
+
+(define_insn "flushda"
+  [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
+                       UNSPECV_FLUSHDA)]
+  ""
+  "flushda\\t%0"
+  [(set_attr "type" "control")])
+
+;; R2 Instructions
+
+(define_insn "wrpie"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")]
+                            UNSPECV_WRPIE))]
+  "TARGET_ARCH_R2"
+  "wrpie\\t%0, %1"
+  [(set_attr "type" "control")])
+
+(define_insn "eni"
+  [(unspec:VOID [(match_operand 0 "const_int_operand" "i")]
+                UNSPECV_ENI)]
+  "TARGET_ARCH_R2"
+  "eni\\t%0"
+  [(set_attr "type" "control")])
+
 ;; Trap patterns
 (define_insn "trap"
   [(trap_if (const_int 1) (const_int 3))]
   emit_move_insn (operands[0], gen_rtx_REG (Pmode, TP_REGNO));
   DONE;
 })
+
+;; Synchronization Primitives
+(include "sync.md")
+
 ;; Include the ldwm/stwm/push.n/pop.n patterns and peepholes.
 (include "ldstwm.md")
 
index 3f2d441c4ea19d1baa2ee4921070780edde72256..f1de2f4edb36ba7bd2846261a9a164696c5d00f1 100644 (file)
   (and (match_code "const_int")
        (match_test "RDWRCTL_INT (INTVAL (op))")))
 
+(define_predicate "rdprs_dcache_operand"
+  (and (match_code "const_int")
+       (if_then_else (match_test "TARGET_ARCH_R2")
+                     (match_test "SMALL_INT12 (INTVAL (op))")
+                     (match_test "SMALL_INT (INTVAL (op))"))))
+
 (define_predicate "custom_insn_opcode"
   (and (match_code "const_int")
        (match_test "CUSTOM_INSN_OPCODE (INTVAL (op))")))
     }
   return memory_operand (op, mode);
 })
+
+(define_predicate "ldstex_memory_operand"
+  (match_code "mem")
+{
+  /* ldex/ldsex/stex/stsex cannot handle memory addresses with offsets.  */
+  return GET_CODE (XEXP (op, 0)) == REG;
+})
diff --git a/gcc/config/nios2/sync.md b/gcc/config/nios2/sync.md
new file mode 100644 (file)
index 0000000..405aa38
--- /dev/null
@@ -0,0 +1,45 @@
+;; Machine Description for Altera Nios II synchronization primitives.
+;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
+;; Contributed by Mentor Graphics, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_int_iterator UNSPECV_LOAD_EXCLUSIVE [UNSPECV_LDEX UNSPECV_LDSEX])
+(define_int_attr load_exclusive [(UNSPECV_LDEX  "ldex")
+                                 (UNSPECV_LDSEX "ldsex")])
+(define_insn "<load_exclusive>"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec_volatile:SI
+          [(match_operand:SI 1 "ldstex_memory_operand" "v")]
+          UNSPECV_LOAD_EXCLUSIVE))]
+  "TARGET_ARCH_R2"
+  "<load_exclusive>\\t%0, %A1"
+  [(set_attr "type" "ld")])
+
+(define_int_iterator UNSPECV_STORE_EXCLUSIVE [UNSPECV_STEX UNSPECV_STSEX])
+(define_int_attr store_exclusive [(UNSPECV_STEX  "stex")
+                                  (UNSPECV_STSEX "stsex")])
+(define_insn "<store_exclusive>"
+  [(set (match_operand:SI 2 "register_operand" "=r")
+        (unspec_volatile:SI [(const_int 0)] UNSPECV_STORE_EXCLUSIVE))
+   (set (match_operand:SI 0 "ldstex_memory_operand" "=v")
+        (unspec_volatile:SI
+          [(match_operand:SI 1 "reg_or_0_operand" "rM")]
+          UNSPECV_STORE_EXCLUSIVE))]
+  "TARGET_ARCH_R2"
+  "<store_exclusive>\\t%2, %z1, %A0"
+  [(set_attr "type" "st")])
index bb858a84f96052b8df55fe00b5903ab4744d26a2..82593b43c89f844564f603f96d2cc96b199f8a2b 100644 (file)
@@ -11045,7 +11045,16 @@ void __builtin_sthio (volatile void *, int)
 void __builtin_stwio (volatile void *, int)
 void __builtin_sync (void)
 int __builtin_rdctl (int) 
+int __builtin_rdprs (int, int)
 void __builtin_wrctl (int, int)
+void __builtin_flushd (volatile void *)
+void __builtin_flushda (volatile void *)
+int __builtin_wrpie (int);
+void __builtin_eni (int);
+int __builtin_ldex (volatile const void *)
+int __builtin_stex (volatile void *, int)
+int __builtin_ldsex (volatile const void *)
+int __builtin_stsex (volatile void *, int)
 @end example
 
 The following built-in functions are always available.  They
index 888380e9011ab7ec75d498481a520615b7a6b545..4fba7acc37eec9f5540f622047bf345c4c6c03f7 100644 (file)
@@ -2999,6 +2999,14 @@ 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 U
+Matches constants suitable as an operand for the rdprs and
+cache instructions.
+
+@item v
+A memory operand suitable for Nios II R2 load/store
+exclusive instructions.
+
 @item w
 A memory operand suitable for load/store IO and cache
 instructions.
index d022c4c2dfd2a30b313ccd88ab93ce6e1ba6c0ea..f961db7c3ba3614c79bf0ecd808e004161a737a9 100644 (file)
@@ -1,3 +1,13 @@
+2015-07-14  Sandra Loosemore  <sandra@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+           Chung-Lin Tang  <cltang@codesourcery.com>
+
+       * gcc.target/nios2/nios2-flushd.c: New.
+       * gcc.target/nios2/nios2-rdprs.c: New.
+       * gcc.target/nios2/r2-atomic.c: New.
+       * gcc.target/nios2/r2-eni.c: New.
+       * gcc.target/nios2/r2-wrpie.c: New.
+
 2015-07-14  Sandra Loosemore  <sandra@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
            Chung-Lin Tang  <cltang@codesourcery.com>
diff --git a/gcc/testsuite/gcc.target/nios2/nios2-flushd.c b/gcc/testsuite/gcc.target/nios2/nios2-flushd.c
new file mode 100644 (file)
index 0000000..8c9a9be
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do assemble } */
+/* { dg-options "-O" } */
+
+void test_flushd (unsigned char* p1, unsigned char* p2)
+{
+  __builtin_flushd (p1);
+  __builtin_flushd (p2);
+  __builtin_flushd (p2 + 1);
+  __builtin_flushd (p2 + 2);
+  __builtin_flushd (p2 + 2047);
+  __builtin_flushd (p2 + 2048);
+}
+
+void test_flushda (unsigned char* p1, unsigned char* p2)
+{
+  __builtin_flushda (p1);
+  __builtin_flushda (p2);
+  __builtin_flushda (p2 + 1);
+  __builtin_flushda (p2 + 2);
+  __builtin_flushda (p2 + 2047);
+  __builtin_flushda (p2 + 2048);
+}
diff --git a/gcc/testsuite/gcc.target/nios2/nios2-rdprs.c b/gcc/testsuite/gcc.target/nios2/nios2-rdprs.c
new file mode 100644 (file)
index 0000000..bea6bbe
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-final { scan-assembler "rdprs" } } */
+
+int x ()
+{
+  __builtin_rdprs (3,934);
+  return 0;
+} 
diff --git a/gcc/testsuite/gcc.target/nios2/r2-atomic.c b/gcc/testsuite/gcc.target/nios2/r2-atomic.c
new file mode 100644 (file)
index 0000000..d4be7ab
--- /dev/null
@@ -0,0 +1,49 @@
+/* { dg-do assemble } */
+/* { dg-options "-O -march=r2" } */
+
+int test_stex (unsigned char* p1, unsigned char* p2)
+{
+  int a, b, c, d;
+  a = __builtin_stex (p1, *p2);
+  b = __builtin_stex (p2, 0);
+  c = __builtin_stex (p2 + 1, 0x80);
+  d = __builtin_stex (p2 + 2, 0x7f);
+
+  return a + b + c + d;
+}
+
+int test_stsex (unsigned short* p1, unsigned short* p2)
+{
+  int a, b, c, d;
+  
+  a = __builtin_stsex (p1, *p2);
+  b = __builtin_stsex (p2, 0);
+  c = __builtin_stsex (p2 + 1, 0x8000);
+  d = __builtin_stsex (p2 + 2, 0x7fff);
+
+  return a + b + c + d;
+}
+
+int test_ldex (unsigned char* p1, unsigned char* p2)
+{
+  int a, b, c, d;
+  
+  a = __builtin_ldex (p1);
+  b = __builtin_ldex (p2);
+  c = __builtin_ldex (p2 + 1);
+  d = __builtin_ldex (p2 + 2);
+
+  return a + b + c + d;
+}
+
+int test_ldsex (unsigned char* p1, unsigned char* p2)
+{
+  int a, b, c, d;
+  
+  a = __builtin_ldsex (p1);
+  b = __builtin_ldsex (p2);
+  c = __builtin_ldsex (p2 + 1);
+  d = __builtin_ldsex (p2 + 2);
+
+  return a + b + c + d;
+}
diff --git a/gcc/testsuite/gcc.target/nios2/r2-eni.c b/gcc/testsuite/gcc.target/nios2/r2-eni.c
new file mode 100644 (file)
index 0000000..85c448a
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=r2" } */
+/* { dg-final { scan-assembler "eni" } } */
+
+void
+foo (void)
+{
+  __builtin_eni (0);
+  __builtin_eni (1);
+}
diff --git a/gcc/testsuite/gcc.target/nios2/r2-wrpie.c b/gcc/testsuite/gcc.target/nios2/r2-wrpie.c
new file mode 100644 (file)
index 0000000..fe9da11
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=r2" } */
+/* { dg-final { scan-assembler "wrpie" } } */
+
+int
+foo (int a)
+{
+  int b;
+
+  b = __builtin_wrpie (a);
+  a = __builtin_wrpie (b);
+
+  return a + b;
+}