diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc
index 353ac69..e98692a 100644
--- a/gcc/config/arc/arc.cc
+++ b/gcc/config/arc/arc.cc
@@ -4256,6 +4256,17 @@ arc_split_ashl (rtx *operands)
 	    }
 	  return;
 	}
+      else if (n >= 16 && n <= 22 && TARGET_SWAP && TARGET_V2)
+	{
+	  emit_insn (gen_ashlsi2_cnt16 (operands[0], operands[1]));
+	  if (n > 16)
+	    {
+	      operands[1] = operands[0];
+	      operands[2] = GEN_INT (n - 16);
+	      arc_split_ashl (operands);
+	    }
+	  return;
+	}
       else if (n >= 29)
 	{
 	  if (n < 31)
@@ -4300,6 +4311,15 @@ arc_split_ashr (rtx *operands)
 	    emit_move_insn (operands[0], operands[1]);
 	  return;
 	}
+      else if (n >= 16 && n <= 18 && TARGET_SWAP)
+	{
+	  emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
+	  emit_insn (gen_extendhisi2 (operands[0],
+				      gen_lowpart (HImode, operands[0])));
+	  while (--n >= 16)
+	    emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
+	  return;
+	}
       else if (n == 30)
 	{
 	  rtx tmp = gen_reg_rtx (SImode);
@@ -4339,6 +4359,13 @@ arc_split_lshr (rtx *operands)
 	    emit_move_insn (operands[0], operands[1]);
 	  return;
 	}
+      else if (n >= 16 && n <= 19 && TARGET_SWAP && TARGET_V2)
+	{
+	  emit_insn (gen_lshrsi2_cnt16 (operands[0], operands[1]));
+	  while (--n >= 16)
+	    emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
+	  return;
+	}
       else if (n == 30)
 	{
 	  rtx tmp = gen_reg_rtx (SImode);
@@ -4385,6 +4412,19 @@ arc_split_rotl (rtx *operands)
 	    emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
 	  return;
 	}
+      else if (n >= 13 && n <= 16 && TARGET_SWAP)
+	{
+	  emit_insn (gen_rotlsi2_cnt16 (operands[0], operands[1]));
+	  while (++n <= 16)
+	    emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
+	  return;
+	}
+      else if (n == 17 && TARGET_SWAP)
+	{
+	  emit_insn (gen_rotlsi2_cnt16 (operands[0], operands[1]));
+	  emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
+	  return;
+	}
       else if (n >= 16 || n == 12 || n == 14)
 	{
 	  emit_insn (gen_rotrsi3_loop (operands[0], operands[1],
@@ -4415,6 +4455,19 @@ arc_split_rotr (rtx *operands)
 	    emit_move_insn (operands[0], operands[1]);
 	  return;
 	}
+      else if (n == 15 && TARGET_SWAP)
+	{
+	  emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
+	  emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
+	  return;
+	}
+      else if (n >= 16 && n <= 19 && TARGET_SWAP)
+	{
+	  emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
+	  while (--n >= 16)
+	    emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
+	  return;
+	}
       else if (n >= 30)
 	{
 	  emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[1]));
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index ee43887..7d5a124 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -3353,6 +3353,7 @@ archs4x, archs4xd"
 
 ;; Shift instructions.
 
+(define_code_iterator ANY_ROTATE [rotate rotatert])
 (define_code_iterator ANY_SHIFT_ROTATE [ashift ashiftrt lshiftrt
 					rotate rotatert])
 
@@ -3415,6 +3416,37 @@ archs4x, archs4xd"
    (set_attr "predicable" "no,no,yes,no,no")
    (set_attr "cond" "nocond,canuse,canuse,nocond,nocond")])
 
+(define_insn "<insn>si2_cnt16"
+  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
+	(ANY_ROTATE:SI (match_operand:SI 1 "register_operand" "c")
+		       (const_int 16)))]
+  "TARGET_SWAP"
+  "swap\\t%0,%1"
+  [(set_attr "length" "4")
+   (set_attr "type" "two_cycle_core")])
+
+(define_insn "ashlsi2_cnt16"
+  [(set (match_operand:SI 0 "register_operand"             "=r")
+	(ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
+		   (const_int 16)))]
+  "TARGET_SWAP && TARGET_V2"
+  "lsl16\\t%0,%1"
+  [(set_attr "type" "shift")
+   (set_attr "iscompact" "false")
+   (set_attr "length" "4")
+   (set_attr "predicable" "no")])
+
+(define_insn "lshrsi2_cnt16"
+  [(set (match_operand:SI 0 "register_operand"               "=r")
+	(lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "rL")
+		     (const_int 16)))]
+  "TARGET_SWAP && TARGET_V2"
+  "lsr16\\t%0,%1"
+  [(set_attr "type" "shift")
+   (set_attr "iscompact" "false")
+   (set_attr "length" "4")
+   (set_attr "predicable" "no")])
+
 ;; Split asl dst,1,src into bset dst,0,src.
 (define_insn_and_split "*ashlsi3_1"
   [(set (match_operand:SI 0 "dest_reg_operand")
@@ -5929,17 +5961,6 @@ archs4x, archs4xd"
    (set_attr "length" "4")
    (set_attr "predicable" "no")])
 
-(define_insn "*ashlsi2_cnt16"
-  [(set (match_operand:SI 0 "register_operand"            "=r")
-	(ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
-		   (const_int 16)))]
-  "TARGET_SWAP && TARGET_V2"
-  "lsl16\\t%0,%1"
-  [(set_attr "type" "shift")
-   (set_attr "iscompact" "false")
-   (set_attr "length" "4")
-   (set_attr "predicable" "no")])
-
 (define_insn "lshrsi3_cnt1"
   [(set (match_operand:SI 0 "dest_reg_operand"             "=q,w")
 	(lshiftrt:SI (match_operand:SI 1 "register_operand" "q,c")
diff --git a/gcc/testsuite/gcc.target/arc/lsl16-1.c b/gcc/testsuite/gcc.target/arc/lsl16-1.c
new file mode 100644
index 0000000..cbd0dae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/lsl16-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em -mswap" } */
+
+int foo(int x)
+{
+  return x << 16;
+}
+
+/* { dg-final { scan-assembler "lsl16\\s+r0,r0" } } */
+
diff --git a/gcc/testsuite/gcc.target/arc/lsr16-1.c b/gcc/testsuite/gcc.target/arc/lsr16-1.c
new file mode 100644
index 0000000..8ce5f13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/lsr16-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em -mswap" } */
+
+unsigned int foo(unsigned int x)
+{
+  return x >> 16;
+}
+
+/* { dg-final { scan-assembler "lsr16\\s+r0,r0" } } */
+
diff --git a/gcc/testsuite/gcc.target/arc/swap-1.c b/gcc/testsuite/gcc.target/arc/swap-1.c
new file mode 100644
index 0000000..71afc75
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/swap-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em -mswap" } */
+
+int foo(int x)
+{
+  return ((unsigned int)x >> 16) | (x << 16);
+}
+
+/* { dg-final { scan-assembler "swap\\s+r0,r0" } } */
diff --git a/gcc/testsuite/gcc.target/arc/swap-2.c b/gcc/testsuite/gcc.target/arc/swap-2.c
new file mode 100644
index 0000000..bf12392
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/swap-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=em -mswap" } */
+
+int foo(int x)
+{
+  return x >> 16;
+}
+
+/* { dg-final { scan-assembler "swap\\s+r0,r0" } } */
+/* { dg-final { scan-assembler "sexh_s\\s+r0,r0" } } */
+
