diff mbox

[5/7,ARC] Update various patterns

Message ID 1500885779-12930-6-git-send-email-claziss@synopsys.com
State New
Headers show

Commit Message

Claudiu Zissulescu July 24, 2017, 8:42 a.m. UTC
From: claziss <claziss@synopsys.com>

gcc/
2017-04-25  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc.md (movqi_insn): Add stores to save constant long
	immediates.
	(movhi_insn): Update store instruction constraint which are saving
	6-bit short immediates.
	(movsi_insn): Consider also short scaled load operations.
	(zero_extendhisi2_i): Use Usd constraint instead of T.
	(extendhisi2_i): Add q constraint.
	(arc_clzsi2): Add type and length attributes.
	(arc_ctzsi2): Likewise.
	* config/arc/constraints.md (Usc): Update constraint, the
	assembler can parse two relocations for a single instruction.

gcc/testsuite/
2017-04-25  Claudiu Zissulescu  <claziss@synopsys.com>

	* gcc.target/arc/arc.exp: Test also cpp files.
	* gcc.target/arc/tdelay_slots.cpp: New test.
---
 gcc/config/arc/arc.md                         | 54 ++++++++++++++-------------
 gcc/config/arc/constraints.md                 |  6 +--
 gcc/testsuite/gcc.target/arc/arc.exp          |  2 +-
 gcc/testsuite/gcc.target/arc/tdelay_slots.cpp | 42 +++++++++++++++++++++
 4 files changed, 75 insertions(+), 29 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/tdelay_slots.cpp

Comments

Andrew Burgess Aug. 31, 2017, 6:57 p.m. UTC | #1
* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2017-07-24 10:42:57 +0200]:

> From: claziss <claziss@synopsys.com>
> 
> gcc/
> 2017-04-25  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc.md (movqi_insn): Add stores to save constant long
> 	immediates.
> 	(movhi_insn): Update store instruction constraint which are saving
> 	6-bit short immediates.
> 	(movsi_insn): Consider also short scaled load operations.
> 	(zero_extendhisi2_i): Use Usd constraint instead of T.
> 	(extendhisi2_i): Add q constraint.
> 	(arc_clzsi2): Add type and length attributes.
> 	(arc_ctzsi2): Likewise.
> 	* config/arc/constraints.md (Usc): Update constraint, the
> 	assembler can parse two relocations for a single instruction.
> 
> gcc/testsuite/
> 2017-04-25  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* gcc.target/arc/arc.exp: Test also cpp files.
> 	* gcc.target/arc/tdelay_slots.cpp: New test.

That looks fine to me.

Thanks,
Andrew



> ---
>  gcc/config/arc/arc.md                         | 54 ++++++++++++++-------------
>  gcc/config/arc/constraints.md                 |  6 +--
>  gcc/testsuite/gcc.target/arc/arc.exp          |  2 +-
>  gcc/testsuite/gcc.target/arc/tdelay_slots.cpp | 42 +++++++++++++++++++++
>  4 files changed, 75 insertions(+), 29 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arc/tdelay_slots.cpp
> 
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index f595da7..04a1447 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -618,8 +618,8 @@
>  ; 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,Rcq#q,   h, w,w,???w,h, w,Rcq,  S,!*x,  r,r, Ucm,m,???m,Usc")
> -	(match_operand:QI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1,cL,I,?Rac,i,?i,  T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3"))]
> +  [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,???w,h, w,Rcq,  S,!*x,  r,r, Ucm,m,???m,  m,Usc")
> +	(match_operand:QI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1,cL,I,?Rac,i,?i,  T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
>    "register_operand (operands[0], QImode)
>     || register_operand (operands[1], QImode)"
>    "@
> @@ -641,11 +641,12 @@
>     xstb%U0 %1,%0
>     stb%U0%V0 %1,%0
>     stb%U0%V0 %1,%0
> +   stb%U0%V0 %1,%0
>     stb%U0%V0 %1,%0"
> -  [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store")
> -   (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false")
> -   (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no")
> -   (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
> +  [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store,store")
> +   (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false,false")
> +   (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no")
> +   (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
>  
>  (define_expand "movhi"
>    [(set (match_operand:HI 0 "move_dest_operand" "")
> @@ -654,8 +655,8 @@
>    "if (prepare_move_operands (operands, HImode)) DONE;")
>  
>  (define_insn "*movhi_insn"
> -  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,???w,Rcq#q,h, w,Rcq,  S,  r,r, Ucm,m,???m,VUsc,VUsc")
> -	(match_operand:HI 1 "move_src_operand" "   cL,   cP,Rcq#q,    P,hCm1,cL,I,?Rac,    i,i,?i,  T,Rcq,Ucm,m,?Rac,c,?Rac, Cm3,i"))]
> +  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,???w,Rcq#q,h, w,Rcq,  S,  r,r, Ucm,m,???m,  m,VUsc")
> +	(match_operand:HI 1 "move_src_operand" "   cL,   cP,Rcq#q,    P,hCm1,cL,I,?Rac,    i,i,?i,  T,Rcq,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
>    "register_operand (operands[0], HImode)
>     || register_operand (operands[1], HImode)
>     || (CONSTANT_P (operands[1])
> @@ -706,8 +707,8 @@
>  ; insns it should lengthen the return insn.
>  ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
>  (define_insn "*movsi_insn"                      ;   0     1     2     3    4  5 6   7   8   9   10  11  12  13    14  15   16  17  18     19     20  21  22    23    24 25 26    27 28  29   30   31
> -  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,  w,  w,  w,  w,???w, ?w,  w,Rcq#q,  h,   w,Rcq,  S,   Us<,RcqRck,!*x,  r,!*Rsd,!*Rcd,r,Ucm,  Usd,m,???m,VUsc,VUsc")
> -	(match_operand:SI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,Cal,?Cal,  T,Rcq,RcqRck,   Us>,Usd,Ucm,  Usd,  Ucd,m,  w,!*Rzd,c,?Rac, Cm3, C32"))]
> +  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,  w,  w,  w,  w,???w, ?w,  w,Rcq#q,  h,   w,Rcq,  S,   Us<,RcqRck,!*x,  r,!*Rsd,!*Rcd,r,Ucm,  Usd,m,???m,  m,VUsc")
> +	(match_operand:SI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,Cal,?Cal,Uts,Rcq,RcqRck,   Us>,Usd,Ucm,  Usd,  Ucd,m,  w,!*Rzd,c,?Rac,Cm3, C32"))]
>    "register_operand (operands[0], SImode)
>     || register_operand (operands[1], SImode)
>     || (CONSTANT_P (operands[1])
> @@ -730,10 +731,10 @@
>     mov%? %0,%1		;11
>     add %0,%S1		;12
>     add %0,pcl,%1@pcl    ;13
> -   mov%? %0,%S1%&	;14
> -   mov%? %0,%S1		;15
> -   mov%? %0,%S1		;16
> -   ld%? %0,%1%&		;17
> +   mov%? %0,%1  	;14
> +   mov%? %0,%1		;15
> +   mov%? %0,%1		;16
> +   ld%?%U1 %0,%1	;17
>     st%? %1,%0%&		;18
>     * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
>     * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
> @@ -747,13 +748,13 @@
>     st%U0%V0 %1,%0	;28
>     st%U0%V0 %1,%0	;29
>     st%U0%V0 %1,%0	;30
> -   st%U0%V0 %S1,%0	;31"
> +   st%U0%V0 %1,%0	;31"
>     ;                         0     1     2     3    4    5      6       7           8     9    10     11    12    13           14        15    16   17    18    19   20    21    22   23  24    25    26    27    28    29   30   31
>    [(set_attr "type"       "move, move, move,move,move, move, move,two_cycle_core,shift,shift,shift, move,binary,binary,      move,      move, move,load,store,store,load,load, load,load,load, load,store,store,store,store,store,store")
>     (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,         false,false,false,false,false, false, false,maybe_limm,maybe_limm,false,true, true, true,true,true,false,true,true,false,false, true,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,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,4,8")
> +   (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,*,8")
>     (set_attr "predicable" "yes,no,yes,no,no,yes,no,no,no,no,no,yes,no,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no")
>     (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")])
>  
> @@ -1634,7 +1635,7 @@
>  )
>  
>  (define_insn "*zero_extendqisi2_ac"
> -  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r")
> +  [(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")))]
>    ""
>    "@
> @@ -1659,19 +1660,19 @@
>  
>  (define_insn "*zero_extendhisi2_i"
>    [(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")))]
> +	(zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,T,Ucm,m")))]
>    ""
>    "@
>     ext%_%? %0,%1%&
>     ext%_%? %0,%1%&
>     bmsk%? %0,%1,15
>     ext%_ %0,%1
> -   ld%_%? %0,%1%&
> -   ld%_%U1 %0,%1
> +   ld%_%? %0,%1
> +   ld%_%? %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,load")
> -   (set_attr "iscompact" "maybe,true,false,false,true,false,false,false")
> +   (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
>     (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
>  
>  
> @@ -1726,7 +1727,7 @@
>  )
>  
>  (define_insn "*extendhisi2_i"
> -  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcq,r,r")
> +  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcqq,r,r")
>  	(sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))]
>    ""
>    "@
> @@ -4524,7 +4525,9 @@
>         gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
>         gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
>    DONE;
> -})
> +}
> +[(set_attr "type" "unary")
> + (set_attr "length" "12")])
>  
>  (define_expand "ctzsi2"
>    [(match_operand:SI 0 "register_operand" "")
> @@ -4567,8 +4570,9 @@
>         gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31),
>  						operands[0]))));
>    DONE;
> -})
> -
> +}
> +[(set_attr "type" "unary")
> + (set_attr "length" "20")])
>  
>  (define_insn "swap"
>    [(set (match_operand:SI  0 "dest_reg_operand" "=w,w,w")
> diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
> index 0ad318c..b8a4a90 100644
> --- a/gcc/config/arc/constraints.md
> +++ b/gcc/config/arc/constraints.md
> @@ -357,13 +357,13 @@
>     (and (match_code "mem")
>  	(match_test "compact_sda_memory_operand (op, VOIDmode, true)")))
>  
> +; Usc constant is only used for storing long constants, hence we can
> +; have only [b,s9], and [b] types of addresses.
>  (define_memory_constraint "Usc"
>    "@internal
>     A valid memory operand for storing constants"
>    (and (match_code "mem")
> -       (match_test "!CONSTANT_P (XEXP (op,0))")
> -;; ??? the assembler rejects stores of immediates to small data.
> -       (match_test "!compact_sda_memory_operand (op, VOIDmode, false)")))
> +       (match_test "!CONSTANT_P (XEXP (op,0))")))
>  
>  (define_constraint "Us<"
>    "@internal
> diff --git a/gcc/testsuite/gcc.target/arc/arc.exp b/gcc/testsuite/gcc.target/arc/arc.exp
> index 00b5c33..5bb09d8 100644
> --- a/gcc/testsuite/gcc.target/arc/arc.exp
> +++ b/gcc/testsuite/gcc.target/arc/arc.exp
> @@ -104,7 +104,7 @@ if ![info exists DEFAULT_CFLAGS] then {
>  dg-init
>  
>  # Main loop.
> -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
> +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{\[cS\],cpp}]] \
>  	"" $DEFAULT_CFLAGS
>  
>  # All done.
> diff --git a/gcc/testsuite/gcc.target/arc/tdelay_slots.cpp b/gcc/testsuite/gcc.target/arc/tdelay_slots.cpp
> new file mode 100644
> index 0000000..3a6d379
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/tdelay_slots.cpp
> @@ -0,0 +1,42 @@
> +/* { dg-do assemble } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
> +/* { dg-options "-O2 -mcpu=em" } */
> +
> +template <class> struct A;
> +int a;
> +template <> struct A<char> {
> +  typedef int int_type;
> +  static int_type eof();
> +};
> +template <> struct A<wchar_t> {
> +  typedef int int_type;
> +  static int_type eof() { return -1; }
> +};
> +class basic_streambuf {
> +public:
> +  virtual ~basic_streambuf();
> +};
> +class B {
> +  void tie();
> +  class C {
> +    C();
> +  };
> +};
> +template <typename _CharT, typename _Traits = A<_CharT>>
> +class D : basic_streambuf {
> +  typedef _Traits traits_type;
> +  typename traits_type::int_type _M_unget_buf;
> +
> +public:
> +  D(void *) : _M_unget_buf(traits_type::eof()) {}
> +};
> +
> +extern D<wchar_t> b;
> +B c;
> +void *operator new(unsigned, void *p2) { return p2; }
> +
> +B::C::C() {
> +  new D<char>(&a);
> +  c.tie();
> +  new (&b) D<wchar_t>(&a);
> +}
> -- 
> 1.9.1
>
Claudiu Zissulescu Sept. 1, 2017, 11:50 a.m. UTC | #2
> That looks fine to me.

Committed. Thank you for your review,
Claudiu
diff mbox

Patch

diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index f595da7..04a1447 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -618,8 +618,8 @@ 
 ; 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,Rcq#q,   h, w,w,???w,h, w,Rcq,  S,!*x,  r,r, Ucm,m,???m,Usc")
-	(match_operand:QI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1,cL,I,?Rac,i,?i,  T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3"))]
+  [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,???w,h, w,Rcq,  S,!*x,  r,r, Ucm,m,???m,  m,Usc")
+	(match_operand:QI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1,cL,I,?Rac,i,?i,  T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
   "register_operand (operands[0], QImode)
    || register_operand (operands[1], QImode)"
   "@
@@ -641,11 +641,12 @@ 
    xstb%U0 %1,%0
    stb%U0%V0 %1,%0
    stb%U0%V0 %1,%0
+   stb%U0%V0 %1,%0
    stb%U0%V0 %1,%0"
-  [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false")
-   (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
+  [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false,false")
+   (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 (define_expand "movhi"
   [(set (match_operand:HI 0 "move_dest_operand" "")
@@ -654,8 +655,8 @@ 
   "if (prepare_move_operands (operands, HImode)) DONE;")
 
 (define_insn "*movhi_insn"
-  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,???w,Rcq#q,h, w,Rcq,  S,  r,r, Ucm,m,???m,VUsc,VUsc")
-	(match_operand:HI 1 "move_src_operand" "   cL,   cP,Rcq#q,    P,hCm1,cL,I,?Rac,    i,i,?i,  T,Rcq,Ucm,m,?Rac,c,?Rac, Cm3,i"))]
+  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,???w,Rcq#q,h, w,Rcq,  S,  r,r, Ucm,m,???m,  m,VUsc")
+	(match_operand:HI 1 "move_src_operand" "   cL,   cP,Rcq#q,    P,hCm1,cL,I,?Rac,    i,i,?i,  T,Rcq,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
   "register_operand (operands[0], HImode)
    || register_operand (operands[1], HImode)
    || (CONSTANT_P (operands[1])
@@ -706,8 +707,8 @@ 
 ; insns it should lengthen the return insn.
 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
 (define_insn "*movsi_insn"                      ;   0     1     2     3    4  5 6   7   8   9   10  11  12  13    14  15   16  17  18     19     20  21  22    23    24 25 26    27 28  29   30   31
-  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,  w,  w,  w,  w,???w, ?w,  w,Rcq#q,  h,   w,Rcq,  S,   Us<,RcqRck,!*x,  r,!*Rsd,!*Rcd,r,Ucm,  Usd,m,???m,VUsc,VUsc")
-	(match_operand:SI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,Cal,?Cal,  T,Rcq,RcqRck,   Us>,Usd,Ucm,  Usd,  Ucd,m,  w,!*Rzd,c,?Rac, Cm3, C32"))]
+  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,  w,  w,  w,  w,???w, ?w,  w,Rcq#q,  h,   w,Rcq,  S,   Us<,RcqRck,!*x,  r,!*Rsd,!*Rcd,r,Ucm,  Usd,m,???m,  m,VUsc")
+	(match_operand:SI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,Cal,?Cal,Uts,Rcq,RcqRck,   Us>,Usd,Ucm,  Usd,  Ucd,m,  w,!*Rzd,c,?Rac,Cm3, C32"))]
   "register_operand (operands[0], SImode)
    || register_operand (operands[1], SImode)
    || (CONSTANT_P (operands[1])
@@ -730,10 +731,10 @@ 
    mov%? %0,%1		;11
    add %0,%S1		;12
    add %0,pcl,%1@pcl    ;13
-   mov%? %0,%S1%&	;14
-   mov%? %0,%S1		;15
-   mov%? %0,%S1		;16
-   ld%? %0,%1%&		;17
+   mov%? %0,%1  	;14
+   mov%? %0,%1		;15
+   mov%? %0,%1		;16
+   ld%?%U1 %0,%1	;17
    st%? %1,%0%&		;18
    * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
    * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
@@ -747,13 +748,13 @@ 
    st%U0%V0 %1,%0	;28
    st%U0%V0 %1,%0	;29
    st%U0%V0 %1,%0	;30
-   st%U0%V0 %S1,%0	;31"
+   st%U0%V0 %1,%0	;31"
    ;                         0     1     2     3    4    5      6       7           8     9    10     11    12    13           14        15    16   17    18    19   20    21    22   23  24    25    26    27    28    29   30   31
   [(set_attr "type"       "move, move, move,move,move, move, move,two_cycle_core,shift,shift,shift, move,binary,binary,      move,      move, move,load,store,store,load,load, load,load,load, load,store,store,store,store,store,store")
    (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,         false,false,false,false,false, false, false,maybe_limm,maybe_limm,false,true, true, true,true,true,false,true,true,false,false, true,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,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,4,8")
+   (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,*,8")
    (set_attr "predicable" "yes,no,yes,no,no,yes,no,no,no,no,no,yes,no,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no")
    (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")])
 
@@ -1634,7 +1635,7 @@ 
 )
 
 (define_insn "*zero_extendqisi2_ac"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r")
+  [(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")))]
   ""
   "@
@@ -1659,19 +1660,19 @@ 
 
 (define_insn "*zero_extendhisi2_i"
   [(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")))]
+	(zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,T,Ucm,m")))]
   ""
   "@
    ext%_%? %0,%1%&
    ext%_%? %0,%1%&
    bmsk%? %0,%1,15
    ext%_ %0,%1
-   ld%_%? %0,%1%&
-   ld%_%U1 %0,%1
+   ld%_%? %0,%1
+   ld%_%? %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,load")
-   (set_attr "iscompact" "maybe,true,false,false,true,false,false,false")
+   (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
    (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
 
 
@@ -1726,7 +1727,7 @@ 
 )
 
 (define_insn "*extendhisi2_i"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcq,r,r")
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcqq,r,r")
 	(sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))]
   ""
   "@
@@ -4524,7 +4525,9 @@ 
        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
        gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
   DONE;
-})
+}
+[(set_attr "type" "unary")
+ (set_attr "length" "12")])
 
 (define_expand "ctzsi2"
   [(match_operand:SI 0 "register_operand" "")
@@ -4567,8 +4570,9 @@ 
        gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31),
 						operands[0]))));
   DONE;
-})
-
+}
+[(set_attr "type" "unary")
+ (set_attr "length" "20")])
 
 (define_insn "swap"
   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w,w")
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index 0ad318c..b8a4a90 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -357,13 +357,13 @@ 
    (and (match_code "mem")
 	(match_test "compact_sda_memory_operand (op, VOIDmode, true)")))
 
+; Usc constant is only used for storing long constants, hence we can
+; have only [b,s9], and [b] types of addresses.
 (define_memory_constraint "Usc"
   "@internal
    A valid memory operand for storing constants"
   (and (match_code "mem")
-       (match_test "!CONSTANT_P (XEXP (op,0))")
-;; ??? the assembler rejects stores of immediates to small data.
-       (match_test "!compact_sda_memory_operand (op, VOIDmode, false)")))
+       (match_test "!CONSTANT_P (XEXP (op,0))")))
 
 (define_constraint "Us<"
   "@internal
diff --git a/gcc/testsuite/gcc.target/arc/arc.exp b/gcc/testsuite/gcc.target/arc/arc.exp
index 00b5c33..5bb09d8 100644
--- a/gcc/testsuite/gcc.target/arc/arc.exp
+++ b/gcc/testsuite/gcc.target/arc/arc.exp
@@ -104,7 +104,7 @@  if ![info exists DEFAULT_CFLAGS] then {
 dg-init
 
 # Main loop.
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{\[cS\],cpp}]] \
 	"" $DEFAULT_CFLAGS
 
 # All done.
diff --git a/gcc/testsuite/gcc.target/arc/tdelay_slots.cpp b/gcc/testsuite/gcc.target/arc/tdelay_slots.cpp
new file mode 100644
index 0000000..3a6d379
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/tdelay_slots.cpp
@@ -0,0 +1,42 @@ 
+/* { dg-do assemble } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+template <class> struct A;
+int a;
+template <> struct A<char> {
+  typedef int int_type;
+  static int_type eof();
+};
+template <> struct A<wchar_t> {
+  typedef int int_type;
+  static int_type eof() { return -1; }
+};
+class basic_streambuf {
+public:
+  virtual ~basic_streambuf();
+};
+class B {
+  void tie();
+  class C {
+    C();
+  };
+};
+template <typename _CharT, typename _Traits = A<_CharT>>
+class D : basic_streambuf {
+  typedef _Traits traits_type;
+  typename traits_type::int_type _M_unget_buf;
+
+public:
+  D(void *) : _M_unget_buf(traits_type::eof()) {}
+};
+
+extern D<wchar_t> b;
+B c;
+void *operator new(unsigned, void *p2) { return p2; }
+
+B::C::C() {
+  new D<char>(&a);
+  c.tie();
+  new (&b) D<wchar_t>(&a);
+}