diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index 4f2db7ffb59a0d1327009b2d74649a1da8f08341..5ce92ba261f20a188c9d63aff6e58e8643cfd5fc 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -35,7 +35,7 @@ extern const char *arc_output_libcall (const char *);
 extern int arc_output_commutative_cond_exec (rtx *operands, bool);
 extern bool arc_expand_cpymem (rtx *operands);
 extern bool prepare_move_operands (rtx *operands, machine_mode mode);
-extern void emit_shift (enum rtx_code, rtx, rtx, rtx);
+extern bool arc_pre_reload_split (void);
 extern void arc_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
 extern void arc_split_compare_and_swap (rtx *);
 extern void arc_expand_compare_and_swap (rtx *);
diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc
index f8c9bf17e2c1ecc5071cfc8f7ee85508f357ec71..2a59618ab6a57ebcfbf887277822447265224f5b 100644
--- a/gcc/config/arc/arc.cc
+++ b/gcc/config/arc/arc.cc
@@ -4239,18 +4239,16 @@ arc_unspec_offset (rtx loc, int unspec)
 					       unspec));
 }
 
-/* !TARGET_BARREL_SHIFTER support.  */
-/* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
-   kind of shift.  */
+/* Predicate for pre-reload splitters with associated instructions,
+   which can match any time before the split1 pass (usually combine),
+   then are unconditionally split in that pass and should not be
+   matched again afterwards.  */
 
-void
-emit_shift (enum rtx_code code, rtx op0, rtx op1, rtx op2)
+bool
+arc_pre_reload_split (void)
 {
-  rtx shift = gen_rtx_fmt_ee (code, SImode, op1, op2);
-  rtx pat
-    = ((shift4_operator (shift, SImode) ?  gen_shift_si3 : gen_shift_si3_loop)
-	(op0, op1, op2, shift));
-  emit_insn (pat);
+  return (can_create_pseudo_p ()
+	  && !(cfun->curr_properties & PROP_rtl_split_insns));
 }
 
 /* Output the assembler code for doing a shift.
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 4af7332d6fa05cae7400808f92767b57451107b4..9d5c65944fdc244b33a41868ea7af2505ba822b1 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -3401,70 +3401,19 @@ archs4x, archs4xd"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
 	(ashift:SI (match_operand:SI 1 "register_operand" "")
 		   (match_operand:SI 2 "nonmemory_operand" "")))]
-  ""
-  "
-{
-  if (!TARGET_BARREL_SHIFTER)
-    {
-      emit_shift (ASHIFT, operands[0], operands[1], operands[2]);
-      DONE;
-    }
-}")
+  "")
 
 (define_expand "ashrsi3"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
 	(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
 		     (match_operand:SI 2 "nonmemory_operand" "")))]
-  ""
-  "
-{
-  if (!TARGET_BARREL_SHIFTER)
-    {
-      emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]);
-      DONE;
-    }
-}")
+  "")
 
 (define_expand "lshrsi3"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
 	(lshiftrt:SI (match_operand:SI 1 "register_operand" "")
 		     (match_operand:SI 2 "nonmemory_operand" "")))]
-  ""
-  "
-{
-  if (!TARGET_BARREL_SHIFTER)
-    {
-      emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]);
-      DONE;
-    }
-}")
-
-(define_insn "shift_si3"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=r")
-	(match_operator:SI 3 "shift4_operator"
-			   [(match_operand:SI 1 "register_operand" "0")
-			    (match_operand:SI 2 "const_int_operand" "n")]))
-   (clobber (match_scratch:SI 4 "=&r"))
-   (clobber (reg:CC CC_REG))
-  ]
-  "!TARGET_BARREL_SHIFTER"
-  "* return output_shift (operands);"
-  [(set_attr "type" "shift")
-   (set_attr "length" "16")])
-
-(define_insn "shift_si3_loop"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
-	(match_operator:SI 3 "shift_operator"
-			   [(match_operand:SI 1 "register_operand" "0,0")
-			    (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
-   (clobber (match_scratch:SI 4 "=X,X"))
-   (clobber (reg:SI LP_COUNT))
-   (clobber (reg:CC CC_REG))
-  ]
-  "!TARGET_BARREL_SHIFTER"
-  "* return output_shift (operands);"
-  [(set_attr "type" "shift")
-   (set_attr "length" "16,20")])
+  "")
 
 ; asl, asr, lsr patterns:
 ; There is no point in including an 'I' alternative since only the lowest 5
@@ -3512,6 +3461,183 @@ archs4x, archs4xd"
    (set_attr "predicable" "no,no,no,yes,no,no")
    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
 
+(define_insn_and_split "*ashlsi3_nobs"
+  [(set (match_operand:SI 0 "dest_reg_operand")
+	(ashift:SI (match_operand:SI 1 "register_operand")
+		   (match_operand:SI 2 "nonmemory_operand")))]
+  "!TARGET_BARREL_SHIFTER
+   && operands[2] != const1_rtx
+   && arc_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
+{
+  if (CONST_INT_P (operands[2]))
+    {
+      int n = INTVAL (operands[2]) & 0x1f;
+      if (n <= 9)
+	{
+	  if (n == 0)
+	    emit_move_insn (operands[0], operands[1]);
+	  else if (n <= 2)
+	    {
+	      emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[1]));
+	      if (n == 2)
+		emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
+	    }
+	  else
+	    {
+	      rtx zero = gen_reg_rtx (SImode);
+	      emit_move_insn (zero, const0_rtx);
+	      emit_insn (gen_add_shift (operands[0], operands[1],
+					GEN_INT (3), zero));
+	      for (n -= 3; n >= 3; n -= 3)
+		emit_insn (gen_add_shift (operands[0], operands[0],
+					  GEN_INT (3), zero));
+	      if (n == 2)
+		emit_insn (gen_add_shift (operands[0], operands[0],
+					  const2_rtx, zero));
+	      else if (n)
+		emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
+	    }
+	  DONE;
+	}
+      else if (n >= 29)
+	{
+	  if (n < 31)
+	    {
+	      if (n == 29)
+		{
+		  emit_insn (gen_andsi3_i (operands[0], operands[1],
+					   GEN_INT (7)));
+		  emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
+		}
+	      else
+		emit_insn (gen_andsi3_i (operands[0], operands[1],
+					 GEN_INT (3)));
+	      emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
+	    }
+	  else
+	    emit_insn (gen_andsi3_i (operands[0], operands[1], const1_rtx));
+	  emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
+	  DONE;
+	}
+    }
+
+  rtx shift = gen_rtx_fmt_ee (ASHIFT, SImode, operands[1], operands[2]);
+  emit_insn (gen_shift_si3_loop (operands[0], operands[1],
+				 operands[2], shift));
+  DONE;
+})
+
+(define_insn_and_split "*ashlri3_nobs"
+  [(set (match_operand:SI 0 "dest_reg_operand")
+	(ashiftrt:SI (match_operand:SI 1 "register_operand")
+		     (match_operand:SI 2 "nonmemory_operand")))]
+  "!TARGET_BARREL_SHIFTER
+   && operands[2] != const1_rtx
+   && arc_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
+{
+  if (CONST_INT_P (operands[2]))
+    {
+      int n = INTVAL (operands[2]) & 0x1f;
+      if (n <= 4)
+	{
+	  if (n != 0)
+	    {
+	      emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[1]));
+	      while (--n > 0)
+		emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
+	    }
+	  else 
+	    emit_move_insn (operands[0], operands[1]);
+	  DONE;
+	}
+    }
+
+  rtx pat;
+  rtx shift = gen_rtx_fmt_ee (ASHIFTRT, SImode, operands[1], operands[2]);
+  if (shiftr4_operator (shift, SImode))
+    pat = gen_shift_si3 (operands[0], operands[1], operands[2], shift);
+  else
+    pat = gen_shift_si3_loop (operands[0], operands[1], operands[2], shift);
+  emit_insn (pat);
+  DONE;
+})
+
+(define_insn_and_split "*lshrsi3_nobs"
+  [(set (match_operand:SI 0 "dest_reg_operand")
+	(lshiftrt:SI (match_operand:SI 1 "register_operand")
+		     (match_operand:SI 2 "nonmemory_operand")))]
+  "!TARGET_BARREL_SHIFTER
+   && operands[2] != const1_rtx
+   && arc_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(const_int 0)]
+{
+  if (CONST_INT_P (operands[2]))
+    {
+      int n = INTVAL (operands[2]) & 0x1f;
+      if (n <= 4)
+	{
+	  if (n != 0)
+	    {
+	      emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[1]));
+	      while (--n > 0)
+		emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
+	    }
+	  else 
+	    emit_move_insn (operands[0], operands[1]);
+	  DONE;
+	}
+    }
+
+  rtx pat;
+  rtx shift = gen_rtx_fmt_ee (LSHIFTRT, SImode, operands[1], operands[2]);
+  if (shiftr4_operator (shift, SImode))
+    pat = gen_shift_si3 (operands[0], operands[1], operands[2], shift);
+  else
+    pat = gen_shift_si3_loop (operands[0], operands[1], operands[2], shift);
+  emit_insn (pat);
+  DONE;
+})
+
+;; shift_si3 appears after {ashr,lshr}si3_nobs
+(define_insn "shift_si3"
+  [(set (match_operand:SI 0 "dest_reg_operand" "=r")
+	(match_operator:SI 3 "shiftr4_operator"
+			   [(match_operand:SI 1 "register_operand" "0")
+			    (match_operand:SI 2 "const_int_operand" "n")]))
+   (clobber (match_scratch:SI 4 "=&r"))
+   (clobber (reg:CC CC_REG))
+  ]
+  "!TARGET_BARREL_SHIFTER
+   && operands[2] != const1_rtx"
+  "* return output_shift (operands);"
+  [(set_attr "type" "shift")
+   (set_attr "length" "16")])
+
+;; shift_si3_loop appears after {ashl,ashr,lshr}si3_nobs
+(define_insn "shift_si3_loop"
+  [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
+	(match_operator:SI 3 "shift_operator"
+			   [(match_operand:SI 1 "register_operand" "0,0")
+			    (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
+   (clobber (reg:SI LP_COUNT))
+   (clobber (reg:CC CC_REG))
+  ]
+  "!TARGET_BARREL_SHIFTER
+   && operands[2] != const1_rtx"
+  "* return output_shift (operands);"
+  [(set_attr "type" "shift")
+   (set_attr "length" "16,20")])
+
+;; Rotate instructions.
+
 (define_insn "rotrsi3"
   [(set (match_operand:SI 0 "dest_reg_operand"                    "=r, r,   r")
 	(rotatert:SI (match_operand:SI 1 "arc_nonmemory_operand"  " 0,rL,rCsz")
@@ -5923,7 +6049,7 @@ archs4x, archs4xd"
 		   (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
    (match_dup 1)])
 
-(define_insn "*rotrsi3_cnt1"
+(define_insn "rotrsi3_cnt1"
   [(set (match_operand:SI 0 "dest_reg_operand"              "=r")
 	(rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL")
 		     (const_int 1)))]
@@ -6342,7 +6468,7 @@ archs4x, archs4xd"
    (set_attr "type" "multi")
    (set_attr "predicable" "yes")])
 
-(define_insn "*add_shift"
+(define_insn "add_shift"
   [(set (match_operand:SI 0 "register_operand" "=q,r,r")
 	(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r")
 			    (match_operand:SI 2 "_1_2_3_operand" ""))
diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md
index 7650e47694d0f427d1d510d3b47e8ae2b588bef9..e37d8844979a537610c1647d3381549cd107d059 100644
--- a/gcc/config/arc/predicates.md
+++ b/gcc/config/arc/predicates.md
@@ -549,16 +549,6 @@
   (match_code "ashiftrt, lshiftrt, ashift")
 )
 
-;; Return true if OP is a left shift operator that can be implemented in
-;; four insn words or less without a barrel shifter or multiplier.
-(define_predicate "shiftl4_operator"
-  (and (match_code "ashift")
-       (match_test "const_int_operand (XEXP (op, 1), VOIDmode) ")
-       (match_test "UINTVAL (XEXP (op, 1)) <= 9U
-		    || INTVAL (XEXP (op, 1)) == 29
-		    || INTVAL (XEXP (op, 1)) == 30
-		    || INTVAL (XEXP (op, 1)) == 31")))
-
 ;; Return true if OP is a right shift operator that can be implemented in
 ;; four insn words or less without a barrel shifter or multiplier.
 (define_predicate "shiftr4_operator"
@@ -568,12 +558,6 @@
 		    || INTVAL (XEXP (op, 1)) == 30
 		    || INTVAL (XEXP (op, 1)) == 31")))
 
-;; Return true if OP is a shift operator that can be implemented in
-;; four insn words or less without a barrel shifter or multiplier.
-(define_predicate "shift4_operator"
-  (ior (match_operand 0 "shiftl4_operator")
-       (match_operand 0 "shiftr4_operator")))
-
 (define_predicate "mult_operator"
     (and (match_code "mult") (match_test "TARGET_MPY"))
 )
diff --git a/gcc/testsuite/gcc.target/arc/ashrsi-1.c b/gcc/testsuite/gcc.target/arc/ashrsi-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..3100aa348ab7883cbc2188b0ec136abc57b52a1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/ashrsi-1.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=hs" } */
+
+int ashr1(int x) { return x >> 1; }
+int ashr2(int x) { return x >> 2; }
+int ashr3(int x) { return x >> 3; }
+int ashr4(int x) { return x >> 4; }
+int ashr5(int x) { return x >> 5; }
+int ashr6(int x) { return x >> 6; }
+int ashr7(int x) { return x >> 7; }
+int ashr8(int x) { return x >> 8; }
+int ashr9(int x) { return x >> 9; }
+int ashr10(int x) { return x >> 10; }
+int ashr11(int x) { return x >> 11; }
+int ashr12(int x) { return x >> 12; }
+int ashr13(int x) { return x >> 13; }
+int ashr14(int x) { return x >> 14; }
+int ashr15(int x) { return x >> 15; }
+int ashr16(int x) { return x >> 16; }
+int ashr17(int x) { return x >> 17; }
+int ashr18(int x) { return x >> 18; }
+int ashr19(int x) { return x >> 19; }
+int ashr20(int x) { return x >> 20; }
+int ashr21(int x) { return x >> 21; }
+int ashr22(int x) { return x >> 22; }
+int ashr23(int x) { return x >> 23; }
+int ashr24(int x) { return x >> 24; }
+int ashr25(int x) { return x >> 25; }
+int ashr26(int x) { return x >> 26; }
+int ashr27(int x) { return x >> 27; }
+int ashr28(int x) { return x >> 28; }
+int ashr29(int x) { return x >> 29; }
+int ashr30(int x) { return x >> 30; }
+int ashr31(int x) { return x >> 31; }
+
+/* { dg-final { scan-assembler-times "asr_s\\s+r0,r0" 31 } } */
diff --git a/gcc/testsuite/gcc.target/arc/ashrsi-2.c b/gcc/testsuite/gcc.target/arc/ashrsi-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..b551ee544b78b69b77bb50bbe8e6db101d22aa27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/ashrsi-2.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+int foo(int x) { return x >> 1; }
+
+/* { dg-final { scan-assembler-times "asr_s\\s+r0,r0" 1 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
diff --git a/gcc/testsuite/gcc.target/arc/ashrsi-3.c b/gcc/testsuite/gcc.target/arc/ashrsi-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..c0306827f17e33edc1247d35c2fa3768b8c9eeec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/ashrsi-3.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+int foo(int x, int y) { return y >> 1; }
+
+/* { dg-final { scan-assembler-times "asr_s\\s+r0,r1" 1 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
diff --git a/gcc/testsuite/gcc.target/arc/ashrsi-4.c b/gcc/testsuite/gcc.target/arc/ashrsi-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..98e58bc57bd9960cb55720319f3297b8b72cfbfb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/ashrsi-4.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+int foo(int x) { return x >> 2; }
+
+/* { dg-final { scan-assembler-times "asr_s\\s+r0,r0" 2 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
diff --git a/gcc/testsuite/gcc.target/arc/ashrsi-5.c b/gcc/testsuite/gcc.target/arc/ashrsi-5.c
new file mode 100644
index 0000000000000000000000000000000000000000..f40af2ed77a4ac6d6481a69364bad1114f6a1064
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/ashrsi-5.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+int foo(int x, int y) { return y >> 2; }
+
+/* { dg-final { scan-assembler-times "asr_s\\s+r0,r0" 1 } } */
+/* { dg-final { scan-assembler-times "asr_s\\s+r0,r1" 1 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
diff --git a/gcc/testsuite/gcc.target/arc/lshrsi-1.c b/gcc/testsuite/gcc.target/arc/lshrsi-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..9bec79d4d0162c205bfa6ddcd175532cfeb91f00
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/lshrsi-1.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=hs" } */
+
+unsigned int lshr1(unsigned int x) { return x >> 1; }
+unsigned int lshr2(unsigned int x) { return x >> 2; }
+unsigned int lshr3(unsigned int x) { return x >> 3; }
+unsigned int lshr4(unsigned int x) { return x >> 4; }
+unsigned int lshr5(unsigned int x) { return x >> 5; }
+unsigned int lshr6(unsigned int x) { return x >> 6; }
+unsigned int lshr7(unsigned int x) { return x >> 7; }
+unsigned int lshr8(unsigned int x) { return x >> 8; }
+unsigned int lshr9(unsigned int x) { return x >> 9; }
+unsigned int lshr10(unsigned int x) { return x >> 10; }
+unsigned int lshr11(unsigned int x) { return x >> 11; }
+unsigned int lshr12(unsigned int x) { return x >> 12; }
+unsigned int lshr13(unsigned int x) { return x >> 13; }
+unsigned int lshr14(unsigned int x) { return x >> 14; }
+unsigned int lshr15(unsigned int x) { return x >> 15; }
+unsigned int lshr16(unsigned int x) { return x >> 16; }
+unsigned int lshr17(unsigned int x) { return x >> 17; }
+unsigned int lshr18(unsigned int x) { return x >> 18; }
+unsigned int lshr19(unsigned int x) { return x >> 19; }
+unsigned int lshr20(unsigned int x) { return x >> 20; }
+unsigned int lshr21(unsigned int x) { return x >> 21; }
+unsigned int lshr22(unsigned int x) { return x >> 22; }
+unsigned int lshr23(unsigned int x) { return x >> 23; }
+unsigned int lshr24(unsigned int x) { return x >> 24; }
+unsigned int lshr25(unsigned int x) { return x >> 25; }
+unsigned int lshr26(unsigned int x) { return x >> 26; }
+unsigned int lshr27(unsigned int x) { return x >> 27; }
+unsigned int lshr28(unsigned int x) { return x >> 28; }
+unsigned int lshr29(unsigned int x) { return x >> 29; }
+unsigned int lshr30(unsigned int x) { return x >> 30; }
+unsigned int lshr31(unsigned int x) { return x >> 31; }
+
+/* { dg-final { scan-assembler-times "lsr_s\\s+r0,r0" 31 } } */
diff --git a/gcc/testsuite/gcc.target/arc/lshrsi-2.c b/gcc/testsuite/gcc.target/arc/lshrsi-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..d8577402feb990d9eb94e0ac8f6d4b49135a3f0f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/lshrsi-2.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+unsigned int foo(unsigned int x) { return x >> 1; }
+
+/* { dg-final { scan-assembler-times "lsr_s\\s+r0,r0" 1 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
diff --git a/gcc/testsuite/gcc.target/arc/lshrsi-3.c b/gcc/testsuite/gcc.target/arc/lshrsi-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..58bfac06e3bd4ad51cd75f73ae9bd3a36b7a839f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/lshrsi-3.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+unsigned int foo(unsigned int x, unsigned int y){ return y >> 1; }
+
+/* { dg-final { scan-assembler-times "lsr_s\\s+r0,r1" 1 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
diff --git a/gcc/testsuite/gcc.target/arc/lshrsi-4.c b/gcc/testsuite/gcc.target/arc/lshrsi-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..3094de2dd49db00c3e534c8716a9cb38ef68deb9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/lshrsi-4.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+unsigned int foo(unsigned int x) { return x >> 2; }
+
+/* { dg-final { scan-assembler-times "lsr_s\\s+r0,r0" 2 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
diff --git a/gcc/testsuite/gcc.target/arc/lshrsi-5.c b/gcc/testsuite/gcc.target/arc/lshrsi-5.c
new file mode 100644
index 0000000000000000000000000000000000000000..dce3f009b38c81c680129069de30551432b7b068
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/lshrsi-5.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+unsigned int foo(unsigned int x, unsigned int y){ return y >> 2; }
+
+/* { dg-final { scan-assembler-times "lsr_s\\s+r0,r0" 1 } } */
+/* { dg-final { scan-assembler-times "lsr_s\\s+r0,r1" 1 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
diff --git a/gcc/testsuite/gcc.target/arc/shlsi-1.c b/gcc/testsuite/gcc.target/arc/shlsi-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..eea7c56cf2e731f3a55ecc028a77577ea83eb718
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/shlsi-1.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=hs" } */
+
+unsigned int shl1(unsigned int x) { return x << 1; }
+unsigned int shl2(unsigned int x) { return x << 2; }
+unsigned int shl3(unsigned int x) { return x << 3; }
+unsigned int shl4(unsigned int x) { return x << 4; }
+unsigned int shl5(unsigned int x) { return x << 5; }
+unsigned int shl6(unsigned int x) { return x << 6; }
+unsigned int shl7(unsigned int x) { return x << 7; }
+unsigned int shl8(unsigned int x) { return x << 8; }
+unsigned int shl9(unsigned int x) { return x << 9; }
+unsigned int shl10(unsigned int x) { return x << 10; }
+unsigned int shl11(unsigned int x) { return x << 11; }
+unsigned int shl12(unsigned int x) { return x << 12; }
+unsigned int shl13(unsigned int x) { return x << 13; }
+unsigned int shl14(unsigned int x) { return x << 14; }
+unsigned int shl15(unsigned int x) { return x << 15; }
+unsigned int shl16(unsigned int x) { return x << 16; }
+unsigned int shl17(unsigned int x) { return x << 17; }
+unsigned int shl18(unsigned int x) { return x << 18; }
+unsigned int shl19(unsigned int x) { return x << 19; }
+unsigned int shl20(unsigned int x) { return x << 20; }
+unsigned int shl21(unsigned int x) { return x << 21; }
+unsigned int shl22(unsigned int x) { return x << 22; }
+unsigned int shl23(unsigned int x) { return x << 23; }
+unsigned int shl24(unsigned int x) { return x << 24; }
+unsigned int shl25(unsigned int x) { return x << 25; }
+unsigned int shl26(unsigned int x) { return x << 26; }
+unsigned int shl27(unsigned int x) { return x << 27; }
+unsigned int shl28(unsigned int x) { return x << 28; }
+unsigned int shl29(unsigned int x) { return x << 29; }
+unsigned int shl30(unsigned int x) { return x << 30; }
+unsigned int shl31(unsigned int x) { return x << 31; }
+
+/* { dg-final { scan-assembler-times "asl_s\\s+r0,r0,\[1-9\]" 31 } } */
diff --git a/gcc/testsuite/gcc.target/arc/shlsi-2.c b/gcc/testsuite/gcc.target/arc/shlsi-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..ab8d2f88da936c576cdd63afcda0a4d7390ea04c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/shlsi-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+unsigned int foo(unsigned int x) { return x << 1; }
+
+/* { dg-final { scan-assembler-times "asl_s\\s+r0,r0" 1 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
+
diff --git a/gcc/testsuite/gcc.target/arc/shlsi-3.c b/gcc/testsuite/gcc.target/arc/shlsi-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..244a7867fef51a5bfaa1f15ab5cdb9b46dae8e35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/shlsi-3.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+unsigned int foo(unsigned int x, unsigned int y) { return y << 1; }
+
+/* { dg-final { scan-assembler-times "asl_s\\s+r0,r1" 1 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
+
diff --git a/gcc/testsuite/gcc.target/arc/shlsi-4.c b/gcc/testsuite/gcc.target/arc/shlsi-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..8fdc25efcac86e923abbaed50bc11ff65926d195
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/shlsi-4.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+unsigned int foo(unsigned int x) { return x << 2; }
+
+/* { dg-final { scan-assembler-times "asl_s\\s+r0,r0" 2 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
+
diff --git a/gcc/testsuite/gcc.target/arc/shlsi-5.c b/gcc/testsuite/gcc.target/arc/shlsi-5.c
new file mode 100644
index 0000000000000000000000000000000000000000..a91103ec1282db378b1057213c70eb33e7ad6210
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/shlsi-5.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em" } */
+
+unsigned int foo(unsigned int x, unsigned int y) { return y << 2; }
+
+/* { dg-final { scan-assembler-times "asl_s\\s+r0,r0" 1 } } */
+/* { dg-final { scan-assembler-times "asl_s\\s+r0,r1" 1 } } */
+/* { dg-final { scan-assembler "j_s\.d" } } */
+