]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
arc.h (SYMBOL_FLAG_CMEM): Define.
authorJoern Rennecke <joern.rennecke@embecosm.com>
Thu, 28 Apr 2016 18:21:42 +0000 (18:21 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Thu, 28 Apr 2016 18:21:42 +0000 (19:21 +0100)
2016-04-28  Joern Rennecke  <joern.rennecke@embecosm.com>
            Andrew Burgess  <andrew.burgess@embecosm.com>
gcc:
        * config/arc/arc.h (SYMBOL_FLAG_CMEM): Define.
        (TARGET_NPS_CMEM_DEFAULT): Provide default definition.
        * config/arc/arc.c (arc_address_cost): Return 0 for cmem_address.
        (arc_encode_section_info): Set SYMBOL_FLAG_CMEM where indicated.
        * config/arc/arc.opt (mcmem): New option.
        * config/arc/arc.md (*extendqihi2_i): Add r/Uex alternative,
        supply length for r/m alternative.
        (*extendqisi2_ac): Likewise.
        (*extendhisi2_i): Add r/Uex alternative, supply length for r/m and
        r/Uex alternative.
        (movqi_insn): Add r/Ucm and Ucm/?Rac alternatives.
        (movhi_insn): Likewise.
        (movsi_insn): Add r/Ucm,Ucm/w alternatives.
        (*zero_extendqihi2_i): Add r/Ucm alternative.
        (*zero_extendqisi2_ac): Likewise.
        (*zero_extendhisi2_i): Likewise.
        * config/arc/constraints.md (Uex): New memory constraint.
        (Ucm): New define_constraint.
        * config/arc/predicates.md (long_immediate_loadstore_operand):
        Return 0 for MEM with cmem_address address.
        (cmem_address_0): New predicates.
        (cmem_address_1): Likewise.
        (cmem_address_2): Likewise.
        (cmem_address): Likewise.
gcc/testsuite:
        * gcc.target/arc/cmem-1.c: New file.
        * gcc.target/arc/cmem-2.c: New file.
        * gcc.target/arc/cmem-3.c: New file.
        * gcc.target/arc/cmem-4.c: New file.
        * gcc.target/arc/cmem-5.c: New file.
        * gcc.target/arc/cmem-6.c: New file.
        * gcc.target/arc/cmem-7.c: New file.
        * gcc.target/arc/cmem-ld.inc: New file.
        * gcc.target/arc/cmem-st.inc: New file.

Co-Authored-By: Andrew Burgess <andrew.burgess@embecosm.com>
From-SVN: r235590

17 files changed:
gcc/ChangeLog
gcc/config/arc/arc.c
gcc/config/arc/arc.h
gcc/config/arc/arc.md
gcc/config/arc/arc.opt
gcc/config/arc/constraints.md
gcc/config/arc/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arc/cmem-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/cmem-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/cmem-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/cmem-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/cmem-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/cmem-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/cmem-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/cmem-ld.inc [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/cmem-st.inc [new file with mode: 0644]

index b223d066d93ffeb78237c7dfc12453eeb4fbbf65..53e5f617befd2ca083f066699292def84d53aefd 100644 (file)
@@ -1,10 +1,39 @@
+2016-04-28  Joern Rennecke  <joern.rennecke@embecosm.com>
+           Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * config/arc/arc.h (SYMBOL_FLAG_CMEM): Define.
+       (TARGET_NPS_CMEM_DEFAULT): Provide default definition.
+       * config/arc/arc.c (arc_address_cost): Return 0 for cmem_address.
+       (arc_encode_section_info): Set SYMBOL_FLAG_CMEM where indicated.
+       * config/arc/arc.opt (mcmem): New option.
+       * config/arc/arc.md (*extendqihi2_i): Add r/Uex alternative,
+       supply length for r/m alternative.
+       (*extendqisi2_ac): Likewise.
+       (*extendhisi2_i): Add r/Uex alternative, supply length for r/m and
+       r/Uex alternative.
+       (movqi_insn): Add r/Ucm and Ucm/?Rac alternatives.
+       (movhi_insn): Likewise.
+       (movsi_insn): Add r/Ucm,Ucm/w alternatives.
+       (*zero_extendqihi2_i): Add r/Ucm alternative.
+       (*zero_extendqisi2_ac): Likewise.
+       (*zero_extendhisi2_i): Likewise.
+       * config/arc/constraints.md (Uex): New memory constraint.
+       (Ucm): New define_constraint.
+       * config/arc/predicates.md (long_immediate_loadstore_operand):
+       Return 0 for MEM with cmem_address address.
+       (cmem_address_0): New predicates.
+       (cmem_address_1): Likewise.
+       (cmem_address_2): Likewise.
+       (cmem_address): Likewise.
+
 2016-04-28  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * config/rs6000/rs6000.c (machine_function): Rename
        insn_chain_scanned_p to spe_insn_chain_scanned_p.
        (rs6000_stack_info): Adjust.
 
-2016-04-28  Andrew Burgess  <andrew.burgess@embecosm.com>
+2016-04-28  Joern Rennecke  <joern.rennecke@embecosm.com>
+           Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * config/arc/constraints.md (Usd): Convert to define_constraint.
        (Us<): Likewise.
index e3744b8c971e0f510b5478bb302b599419feb43d..ca9d31ceee95dbf639f1fa6c667161c686250739 100644 (file)
@@ -1843,6 +1843,8 @@ arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
     case LABEL_REF :
     case SYMBOL_REF :
     case CONST :
+      if (TARGET_NPS_CMEM && cmem_address (addr, SImode))
+       return 0;
       /* Most likely needs a LIMM.  */
       return COSTS_N_INSNS (1);
 
@@ -4337,6 +4339,24 @@ arc_encode_section_info (tree decl, rtx rtl, int first)
 
       SYMBOL_REF_FLAGS (symbol) = flags;
     }
+  else if (TREE_CODE (decl) == VAR_DECL)
+    {
+      rtx symbol = XEXP (rtl, 0);
+
+      tree attr = (TREE_TYPE (decl) != error_mark_node
+                  ? DECL_ATTRIBUTES (decl) : NULL_TREE);
+
+      tree sec_attr = lookup_attribute ("section", attr);
+      if (sec_attr)
+       {
+         const char *sec_name
+           = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
+         if (strcmp (sec_name, ".cmem") == 0
+             || strcmp (sec_name, ".cmem_shared") == 0
+             || strcmp (sec_name, ".cmem_private") == 0)
+           SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
+       }
+    }
 }
 
 /* This is how to output a definition of an internal numbered label where
index b14352c3e2622fe0950941539501a413cd666628..a17d41092507ca98627bd5294430f13241a9ab29 100644 (file)
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.  If not see
 #define SYMBOL_FLAG_SHORT_CALL (SYMBOL_FLAG_MACH_DEP << 0)
 #define SYMBOL_FLAG_MEDIUM_CALL        (SYMBOL_FLAG_MACH_DEP << 1)
 #define SYMBOL_FLAG_LONG_CALL  (SYMBOL_FLAG_MACH_DEP << 2)
+#define SYMBOL_FLAG_CMEM       (SYMBOL_FLAG_MACH_DEP << 3)
 
 /* Check if this symbol has a long_call attribute in its declaration */
 #define SYMBOL_REF_LONG_CALL_P(X)      \
@@ -321,6 +322,14 @@ along with GCC; see the file COPYING3.  If not see
 #define MULTILIB_DEFAULTS { "mARC700" }
 #endif
 
+#ifndef UNALIGNED_ACCESS_DEFAULT
+#define UNALIGNED_ACCESS_DEFAULT 0
+#endif
+
+#ifndef TARGET_NPS_CMEM_DEFAULT
+#define TARGET_NPS_CMEM_DEFAULT 0
+#endif
+
 /* Target machine storage layout.  */
 
 /* We want zero_extract to mean the same
index 8ec0ce0427baa11cd8c2ed1b17eb8c67af35db2d..93a2cad7dfa64711097050bf55886a9463545f30 100644 (file)
 ; The iscompact attribute allows the epilogue expander to know for which
 ; insns it should lengthen the return insn.
 (define_insn "*movqi_insn"
-  [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w, w,Rcq,S,!*x,r,m,???m")
-       (match_operand:QI 1 "move_src_operand"   "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,m,c,?Rac"))]
+  [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,w,Rcq,S,!*x,r,r,Ucm,m,???m")
+       (match_operand:QI 1 "move_src_operand"  "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))]
   "register_operand (operands[0], QImode)
    || register_operand (operands[1], QImode)"
   "@
    ldb%? %0,%1%&
    stb%? %1,%0%&
    ldb%? %0,%1%&
+   xldb%U1 %0,%1
    ldb%U1%V1 %0,%1
+   xstb%U0 %1,%0
    stb%U0%V0 %1,%0
    stb%U0%V0 %1,%0"
-  [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false")
-   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*")])
+  [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,load,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false,false,false")
+   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 (define_expand "movhi"
   [(set (match_operand:HI 0 "move_dest_operand" "")
   "if (prepare_move_operands (operands, HImode)) DONE;")
 
 (define_insn "*movhi_insn"
-  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w,Rcq#q,w,Rcq,S,r,m,???m,VUsc")
-       (match_operand:HI 1 "move_src_operand"   "cL,cP,Rcq#q,cL,I,?Rac,  ?i,?i,T,Rcq,m,c,?Rac,i"))]
+  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,Rcq#q,w,Rcq,S,r,r,Ucm,m,???m,VUsc")
+       (match_operand:HI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,?i,T,Rcq,Ucm,m,?Rac,c,?Rac,i"))]
   "register_operand (operands[0], HImode)
    || register_operand (operands[1], HImode)
    || (CONSTANT_P (operands[1])
    mov%? %0,%S1
    ld%_%? %0,%1%&
    st%_%? %1,%0%&
+   xld%_%U1 %0,%1
    ld%_%U1%V1 %0,%1
+   xst%_%U0 %1,%0
    st%_%U0%V0 %1,%0
    st%_%U0%V0 %1,%0
    st%_%U0%V0 %S1,%0"
-  [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,store,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false")
-   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*")])
+  [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false")
+   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 (define_expand "movsi"
   [(set (match_operand:SI 0 "move_dest_operand" "")
 ; insns it should lengthen the return insn.
 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
 (define_insn "*movsi_insn"
-  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,  w,???w, ?w,  w,Rcq#q, w,Rcq,  S,Us<,RcqRck,!*x,r,m,???m,VUsc")
-       (match_operand:SI 1 "move_src_operand"  " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,m,c,?Rac,C32"))]
+  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,  w,???w, ?w,  w,Rcq#q, w,Rcq,  S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc")
+       (match_operand:SI 1 "move_src_operand"  " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))]
   "register_operand (operands[0], SImode)
    || register_operand (operands[1], SImode)
    || (CONSTANT_P (operands[1])
    * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
    * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
    ld%? %0,%1%&                ;15
-   ld%U1%V1 %0,%1      ;16
-   st%U0%V0 %1,%0       ;17
-   st%U0%V0 %1,%0       ;18
-   st%U0%V0 %S1,%0      ;19"
-  [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,store,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false")
+   xld%U1 %0,%1         ;16
+   ld%U1%V1 %0,%1      ;17
+   xst%U0 %1,%0         ;18
+   st%U0%V0 %1,%0       ;19
+   st%U0%V0 %1,%0       ;20
+   st%U0%V0 %S1,%0      ;21"
+  [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false")
    ; Use default length for iscompact to allow for COND_EXEC.  But set length
    ; of Crr to 4.
-   (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,*,*,*,8")
-   (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
+   (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8")
+   (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 ;; Sometimes generated by the epilogue code.  We don't want to
 ;; recognize these addresses in general, because the limm is costly,
 
 
 (define_insn "*zero_extendqihi2_i"
-  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r")
-       (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,m")))]
+  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r")
+       (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))]
   ""
   "@
    extb%? %0,%1%&
    extb%? %0,%1%&
    bmsk%? %0,%1,7
    extb %0,%1
+   xldb%U1 %0,%1
    ldb%U1 %0,%1"
-  [(set_attr "type" "unary,unary,unary,unary,load")
-   (set_attr "iscompact" "maybe,true,false,false,false")
-   (set_attr "predicable" "no,no,yes,no,no")])
+  [(set_attr "type" "unary,unary,unary,unary,load,load")
+   (set_attr "iscompact" "maybe,true,false,false,false,false")
+   (set_attr "predicable" "no,no,yes,no,no,no")])
 
 (define_expand "zero_extendqihi2"
   [(set (match_operand:HI 0 "dest_reg_operand" "")
 )
 
 (define_insn "*zero_extendqisi2_ac"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r")
-       (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r")
+       (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))]
   ""
   "@
    extb%? %0,%1%&
    extb %0,%1
    ldb%? %0,%1%&
    ldb%? %0,%1%&
+   xldb%U1 %0,%1
    ldb%U1 %0,%1"
-  [(set_attr "type" "unary,unary,unary,unary,load,load,load")
-   (set_attr "iscompact" "maybe,true,false,false,true,true,false")
-   (set_attr "predicable" "no,no,yes,no,no,no,no")])
+  [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
+   (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
+   (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
 
 (define_expand "zero_extendqisi2"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
 )
 
 (define_insn "*zero_extendhisi2_i"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r")
-       (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r")
+       (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,Ucm,m")))]
   ""
   "@
    ext%_%? %0,%1%&
    ext%_ %0,%1
    ld%_%? %0,%1%&
    ld%_%U1 %0,%1
+   * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\";
    ld%_%U1%V1 %0,%1"
-  [(set_attr "type" "unary,unary,unary,unary,load,load,load")
-   (set_attr "iscompact" "maybe,true,false,false,true,false,false")
-   (set_attr "predicable" "no,no,yes,no,no,no,no")])
+  [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
+   (set_attr "iscompact" "maybe,true,false,false,true,false,false,false")
+   (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
 
 
 (define_expand "zero_extendhisi2"
 ;; Sign extension instructions.
 
 (define_insn "*extendqihi2_i"
-  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r")
-       (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,m")))]
+  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r")
+       (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))]
   ""
   "@
    sexb%? %0,%1%&
    sexb %0,%1
+   ldb.x%U1 %0,%1
    ldb.x%U1 %0,%1"
-  [(set_attr "type" "unary,unary,load")
-   (set_attr "iscompact" "true,false,false")])
+  [(set_attr "type" "unary,unary,load,load")
+   (set_attr "iscompact" "true,false,false,false")
+   (set_attr "length" "*,*,*,8")])
 
 
 (define_expand "extendqihi2"
 )
 
 (define_insn "*extendqisi2_ac"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
-       (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
+       (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
   ""
   "@
    sexb%? %0,%1%&
    sexb %0,%1
+   ldb.x%U1 %0,%1
    ldb.x%U1 %0,%1"
-  [(set_attr "type" "unary,unary,load")
-   (set_attr "iscompact" "true,false,false")])
+  [(set_attr "type" "unary,unary,load,load")
+   (set_attr "iscompact" "true,false,false,false")
+   (set_attr "length" "*,*,*,8")])
 
 (define_expand "extendqisi2"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
 )
 
 (define_insn "*extendhisi2_i"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
-       (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
+       (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
   ""
   "@
    sex%_%? %0,%1%&
    sex%_ %0,%1
+   ld%_.x%U1%V1 %0,%1
    ld%_.x%U1%V1 %0,%1"
-  [(set_attr "type" "unary,unary,load")
-   (set_attr "iscompact" "true,false,false")])
+  [(set_attr "type" "unary,unary,load,load")
+   (set_attr "iscompact" "true,false,false,false")
+   (set_attr "length" "*,*,4,8")])
 
 (define_expand "extendhisi2"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
index 45bb6a6167d3f8bd61cfeb666c23266e24de428d..b2c7b3763c1d873a118b64a92defaea2d26136b4 100644 (file)
@@ -469,3 +469,11 @@ Specify thread pointer register number
 
 mtp-regno=none
 Target RejectNegative Var(arc_tp_regno,-1)
+
+mcmem
+Target Report Var(TARGET_NPS_CMEM) Init(TARGET_NPS_CMEM_DEFAULT)
+Enable use of NPS400 xld/xst extension.
+
+munaligned-access
+Target Report Var(unaligned_access) Init(UNALIGNED_ACCESS_DEFAULT)
+Enable unaligned word and halfword accesses to packed data.
index b6954ad9456ab91c8672fa3e50ed73f8ee0c5797..c2992c9e9473f0d0cd72e023fd0a5924223ee112 100644 (file)
   (and (match_code "mem")
        (match_test "compact_store_memory_operand (op, VOIDmode)")))
 
+(define_memory_constraint "Uex"
+  "@internal
+   A valid memory operand for limm-free extend instructions"
+  (and (match_code "mem")
+       (match_test "!cmem_address (XEXP (op, 0), SImode)")
+       (not (match_operand 0 "long_immediate_loadstore_operand"))))
+
 ; Don't use define_memory_constraint here as the relocation patching
 ; for small data symbols only works within a ld/st instruction and
 ; define_memory_constraint may result in the address being calculated
        (match_test "REG_P (XEXP (XEXP (op, 0), 0))")
        (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG")))
 
+(define_constraint "Ucm"
+  "@internal
+  cmem access"
+  (and (match_code "mem")
+       (match_test "TARGET_NPS_CMEM && cmem_address (XEXP (op, 0), VOIDmode)")))
+
 ;; General constraints
 
 (define_constraint "Cbr"
 (define_memory_constraint "ATO"
   "A memory with only a base register"
   (match_operand 0 "mem_noofs_operand"))
-
index 3c657c67f0d3433c9d6942ee20d975dfadaa48ef..0d2e217bf9d66750548c4350dbdb71a83f748285 100644 (file)
   int size = GET_MODE_SIZE (GET_MODE (op));
 
   op = XEXP (op, 0);
+  if (TARGET_NPS_CMEM && cmem_address (op, SImode))
+    return 0;
   switch (GET_CODE (op))
     {
     case SYMBOL_REF :
 (define_predicate "double_register_operand"
   (ior (match_test "even_register_operand (op, mode)")
        (match_test "arc_double_register_operand (op, mode)")))
+
+(define_predicate "cmem_address_0"
+  (and (match_code "symbol_ref")
+       (match_test "SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_CMEM")))
+
+(define_predicate "cmem_address_1"
+  (and (match_code "plus")
+       (match_test "cmem_address_0 (XEXP (op, 0), SImode)")))
+
+(define_predicate "cmem_address_2"
+  (and (match_code "const")
+       (match_test "cmem_address_1 (XEXP (op, 0), SImode)")))
+
+(define_predicate "cmem_address"
+  (ior (match_operand:SI 0 "cmem_address_0")
+       (match_operand:SI 0 "cmem_address_1")
+       (match_operand:SI 0 "cmem_address_2")))
index b787d4a34363ed7184062c56f7f2be45adca53ea..aa8ae68acfd265674fb1e8063f8f99cdd1b6ff2b 100644 (file)
@@ -1,3 +1,16 @@
+2016-04-28  Joern Rennecke  <joern.rennecke@embecosm.com>
+           Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * gcc.target/arc/cmem-1.c: New file.
+       * gcc.target/arc/cmem-2.c: New file.
+       * gcc.target/arc/cmem-3.c: New file.
+       * gcc.target/arc/cmem-4.c: New file.
+       * gcc.target/arc/cmem-5.c: New file.
+       * gcc.target/arc/cmem-6.c: New file.
+       * gcc.target/arc/cmem-7.c: New file.
+       * gcc.target/arc/cmem-ld.inc: New file.
+       * gcc.target/arc/cmem-st.inc: New file.
+
 2016-04-28  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/70821
diff --git a/gcc/testsuite/gcc.target/arc/cmem-1.c b/gcc/testsuite/gcc.target/arc/cmem-1.c
new file mode 100644 (file)
index 0000000..7f36afb
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
+
+#include "cmem-st.inc"
+
+/* { dg-final { scan-assembler "xst " } } */
+/* { dg-final { scan-assembler "xstw " } } */
+/* { dg-final { scan-assembler "xstb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-2.c b/gcc/testsuite/gcc.target/arc/cmem-2.c
new file mode 100644 (file)
index 0000000..a3d7c13
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
+
+#include "cmem-ld.inc"
+
+/* { dg-final { scan-assembler "xld " } } */
+/* { dg-final { scan-assembler "xldw " } } */
+/* { dg-final { scan-assembler "xldb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-3.c b/gcc/testsuite/gcc.target/arc/cmem-3.c
new file mode 100644 (file)
index 0000000..dee73b5
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private")));
+
+#include "cmem-st.inc"
+
+/* { dg-final { scan-assembler "xst " } } */
+/* { dg-final { scan-assembler "xstw " } } */
+/* { dg-final { scan-assembler "xstb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-4.c b/gcc/testsuite/gcc.target/arc/cmem-4.c
new file mode 100644 (file)
index 0000000..1da6bce
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private")));
+
+#include "cmem-ld.inc"
+
+/* { dg-final { scan-assembler "xld " } } */
+/* { dg-final { scan-assembler "xldw " } } */
+/* { dg-final { scan-assembler "xldb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-5.c b/gcc/testsuite/gcc.target/arc/cmem-5.c
new file mode 100644 (file)
index 0000000..ad6904f
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared")));
+
+#include "cmem-st.inc"
+
+/* { dg-final { scan-assembler "xst " } } */
+/* { dg-final { scan-assembler "xstw " } } */
+/* { dg-final { scan-assembler "xstb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-6.c b/gcc/testsuite/gcc.target/arc/cmem-6.c
new file mode 100644 (file)
index 0000000..24bc39b
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared")));
+
+#include "cmem-ld.inc"
+
+/* { dg-final { scan-assembler "xld " } } */
+/* { dg-final { scan-assembler "xldw " } } */
+/* { dg-final { scan-assembler "xldb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-7.c b/gcc/testsuite/gcc.target/arc/cmem-7.c
new file mode 100644 (file)
index 0000000..72ee7bd
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+struct some_struct
+{
+  unsigned char a;
+};
+
+unsigned char other_func (unsigned char);
+
+unsigned char
+some_function ()
+{
+  static struct some_struct ss __attribute__ ((section (".cmem")));
+  static struct some_struct tt;
+
+  ss.a = other_func (ss.a);
+  tt.a = other_func (tt.a);
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler "xldb \[^\n\]*@ss" } } */
+/* { dg-final { scan-assembler "xstb \[^\n\]*@ss" } } */
+/* { dg-final { scan-assembler-not "xldb \[^\n\]*@tt" } } */
+/* { dg-final { scan-assembler-not "xstb \[^\n\]*@tt" } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-ld.inc b/gcc/testsuite/gcc.target/arc/cmem-ld.inc
new file mode 100644 (file)
index 0000000..7b51bb3
--- /dev/null
@@ -0,0 +1,16 @@
+
+struct foo_type
+{
+  unsigned int a;
+  unsigned short b;
+  unsigned char c;
+};
+
+struct foo_type foo __attribute__ ((section (".cmem")));
+
+unsigned int
+f ()
+{
+  unsigned int tmp = foo.a + foo.b + foo.c;
+  return tmp;
+}
diff --git a/gcc/testsuite/gcc.target/arc/cmem-st.inc b/gcc/testsuite/gcc.target/arc/cmem-st.inc
new file mode 100644 (file)
index 0000000..30aeace
--- /dev/null
@@ -0,0 +1,18 @@
+
+struct foo_type
+{
+  unsigned int a;
+  unsigned short b;
+  unsigned char c;
+};
+
+struct foo_type foo CMEM_SECTION_ATTR
+
+int
+f ()
+{
+  foo.a = 3;
+  foo.b = 2;
+  foo.c = 1;
+  return 0;
+}