From 09463827001a7b8094f4b9460514370a1876d908 Mon Sep 17 00:00:00 2001
From: Claudiu Zissulescu <claziss@synopsys.com>
Date: Wed, 20 Jan 2016 16:32:40 +0100
Subject: [PATCH] Don't allow mcompact-casesi for ARCv2

The compact casesi is not working for arcv2 processors family as it
makes use of the add_s rx,rx,pcl instruction which is only valid for
arc6xx and arc700 processors. Also not having this instruction makes
no much sens to change the compact-casesi pattern to use normal add
instructions as it nullifies the advantage of short instruction use.
The default casesi pattern betters suits the arcv2 architecture.

The fix is done in development tree: [arc-4.8-dev 0946382] 
and will be a part of the next release of ARC GNU tools.
Once that new release happens this patch must be removed.

gcc/
2016-01-20  Claudiu Zissulescu  <claziss@synopsys.com>

	* common/config/arc/arc-common.c (arc_option_optimization_table):
	Remove mcompact-casesi option.
	* config/arc/arc.c (arc_override_options): Use compact-casesi only
	for arcv1.
	* config/arc/arc.md (casesi_load): Use short instructions.
---
 gcc/common/config/arc/arc-common.c |  1 -
 gcc/config/arc/arc.c               |  9 +++++----
 gcc/config/arc/arc.md              | 10 ++++++++--
 3 files changed, 13 insertions(+), 7 deletions(-)
 
 	* config/arc/arc.c (arc_legitimize_pic_address): Handle MINUS
diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c
index e2e36fa..310bc80 100644
--- a/gcc/common/config/arc/arc-common.c
+++ b/gcc/common/config/arc/arc-common.c
@@ -58,7 +58,6 @@ static const struct default_options arc_option_optimization_table[] =
     { OPT_LEVELS_ALL, OPT_mbbit_peephole, NULL, 1 },
     { OPT_LEVELS_SIZE, OPT_mq_class, NULL, 1 },
     { OPT_LEVELS_SIZE, OPT_mcase_vector_pcrel, NULL, 1 },
-    { OPT_LEVELS_SIZE, OPT_mcompact_casesi, NULL, 1 },
     { OPT_LEVELS_NONE, 0, NULL, 0 }
   };
 
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 18d88a3..f828398 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -1151,6 +1151,11 @@ arc_override_options (void)
   if (arc_size_opt_level == 3)
     optimize_size = 1;
 
+  if (TARGET_V2)
+    TARGET_COMPACT_CASESI = 0;
+  else if (optimize_size == 1)
+    TARGET_COMPACT_CASESI = 1;
+
   if (flag_pic)
     target_flags |= MASK_NO_SDATA_SET;
 
@@ -1163,10 +1168,6 @@ arc_override_options (void)
   if (!TARGET_Q_CLASS)
     TARGET_COMPACT_CASESI = 0;
 
-  /* For the time being don't support COMPACT_CASESI for ARCv2. */
-  if (TARGET_V2)
-    TARGET_COMPACT_CASESI = 0;
-
   if (TARGET_COMPACT_CASESI)
     TARGET_CASE_VECTOR_PC_RELATIVE = 1;
 
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index bc4ac38..ba7c8bc 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -3837,14 +3837,20 @@
   switch (GET_MODE (diff_vec))
     {
     case SImode:
-      return \"ld.as %0,[%1,%2]%&\";
+      if ((which_alternative == 0) && TARGET_CODE_DENSITY)
+       return \"ld_s.as %0,[%1,%2]%&\";
+      else
+       return \"ld.as %0,[%1,%2]%&\";
     case HImode:
       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
 	return \"ldw.as %0,[%1,%2]\";
       return \"ldw.x.as %0,[%1,%2]\";
     case QImode:
       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
-	return \"ldb%? %0,[%1,%2]%&\";
+        if (which_alternative == 0)
+	 return \"ldb_s %0,[%1,%2]%&\";
+        else
+	 return \"ldb %0,[%1,%2]%&\";
       return \"ldb.x %0,[%1,%2]\";
     default:
       gcc_unreachable ();
-- 
2.5.0

