diff mbox

[2/7,ARC] Use -G option to control sdata behavior

Message ID 1500885779-12930-3-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>

Add support for -G option to ARC backend.

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

	* config.gcc: Use g.opt for arc.
	* config/arc/arc.c (LEGITIMATE_SCALED_ADDRESS_P): Deleted,
	functionality moved to ...
	(legitimate_scaled_address_p): New function, ...here.
	(LEGITIMATE_SMALL_DATA_OFFSET_P): New define.
	(LEGITIMATE_SMALL_DATA_ADDRESS_P): Use the above define.
	(legitimate_offset_address_p): Delete TARGET_NO_SDATA_SET
	condition.
	(arc_override_options): Handle G option.
	(arc_output_pic_addr_const): Correct function definition.
	(arc_legitimate_address_p): Use legitimate_scaled_address_p.
	(arc_decl_anon_ns_mem_p): Delete.
	(arc_in_small_data_p): Overhaul this function to take into
	consideration the value given via G option.
	(arc_rewrite_small_data_1): Renamed and corrected old
	arc_rewrite_small_data function.
	(arc_rewrite_small_data): New function.
	(small_data_pattern): Don't use pic_offset_table_rtx.
	* config/arc/arc.h (CC1_SPEC): Recognize G option.
	* config/arc/simdext.md (movmisalignv2hi): Use
	prepare_move_operands function.
	(mov*): Likewise.
	(movmisalign*): Likewise.

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

	* gcc.target/arc/sdata-5.c: New test.
	* gcc.target/arc/arc700-stld-hazard.c: Update test options.

Fix test
---
 gcc/config.gcc                                    |   2 +-
 gcc/config/arc/arc.c                              | 236 ++++++++++++----------
 gcc/config/arc/arc.h                              |   6 +-
 gcc/config/arc/simdext.md                         |  22 +-
 gcc/testsuite/gcc.target/arc/arc700-stld-hazard.c |   2 +-
 gcc/testsuite/gcc.target/arc/sdata-5.c            |   8 +
 6 files changed, 152 insertions(+), 124 deletions(-)
 create mode 100755 gcc/testsuite/gcc.target/arc/sdata-5.c

Comments

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

> From: claziss <claziss@synopsys.com>
> 
> Add support for -G option to ARC backend.
> 
> gcc/
> 2017-04-24  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config.gcc: Use g.opt for arc.
> 	* config/arc/arc.c (LEGITIMATE_SCALED_ADDRESS_P): Deleted,
> 	functionality moved to ...
> 	(legitimate_scaled_address_p): New function, ...here.
> 	(LEGITIMATE_SMALL_DATA_OFFSET_P): New define.
> 	(LEGITIMATE_SMALL_DATA_ADDRESS_P): Use the above define.
> 	(legitimate_offset_address_p): Delete TARGET_NO_SDATA_SET
> 	condition.
> 	(arc_override_options): Handle G option.
> 	(arc_output_pic_addr_const): Correct function definition.
> 	(arc_legitimate_address_p): Use legitimate_scaled_address_p.
> 	(arc_decl_anon_ns_mem_p): Delete.
> 	(arc_in_small_data_p): Overhaul this function to take into
> 	consideration the value given via G option.
> 	(arc_rewrite_small_data_1): Renamed and corrected old
> 	arc_rewrite_small_data function.
> 	(arc_rewrite_small_data): New function.
> 	(small_data_pattern): Don't use pic_offset_table_rtx.
> 	* config/arc/arc.h (CC1_SPEC): Recognize G option.
> 	* config/arc/simdext.md (movmisalignv2hi): Use
> 	prepare_move_operands function.
> 	(mov*): Likewise.
> 	(movmisalign*): Likewise.
> 
> gcc/testsuite/
> 2017-04-24  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* gcc.target/arc/sdata-5.c: New test.
> 	* gcc.target/arc/arc700-stld-hazard.c: Update test options.

From looking at other targets, I think that we need to add
documentation for -G into the ARC Options section of of
gcc/doc/invoke.texi.

> diff --git a/gcc/testsuite/gcc.target/arc/sdata-5.c b/gcc/testsuite/gcc.target/arc/sdata-5.c
> new file mode 100755
> index 0000000..0fdd52d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/sdata-5.c
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +/* { dg-options "-w -Os" } */
> +
> +const a[1] = {};
> +static short b[] = {};
> +
> +c;
> +fn1() { return a + b[c]; }

Is it critical that we rely on default types here?  I know it's
legitimate, but it just makes me sad to see new code using default
types.

Also, I guess that this test expects some things to be placed into the
small data section? Is there no pattern we can 'scan-assembler' for?
Or is this testing some other feature / bug?

Otherwise seems fine.

Thanks,
Andrew
Sandra Loosemore Aug. 15, 2017, 4:09 p.m. UTC | #2
On 08/15/2017 07:30 AM, Andrew Burgess wrote:
> * Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2017-07-24 10:42:54 +0200]:
>
>> From: claziss <claziss@synopsys.com>
>>
>> Add support for -G option to ARC backend.
>>
>> gcc/
>> 2017-04-24  Claudiu Zissulescu  <claziss@synopsys.com>
>>
>> 	* config.gcc: Use g.opt for arc.
>> 	* config/arc/arc.c (LEGITIMATE_SCALED_ADDRESS_P): Deleted,
>> 	functionality moved to ...
>> 	(legitimate_scaled_address_p): New function, ...here.
>> 	(LEGITIMATE_SMALL_DATA_OFFSET_P): New define.
>> 	(LEGITIMATE_SMALL_DATA_ADDRESS_P): Use the above define.
>> 	(legitimate_offset_address_p): Delete TARGET_NO_SDATA_SET
>> 	condition.
>> 	(arc_override_options): Handle G option.
>> 	(arc_output_pic_addr_const): Correct function definition.
>> 	(arc_legitimate_address_p): Use legitimate_scaled_address_p.
>> 	(arc_decl_anon_ns_mem_p): Delete.
>> 	(arc_in_small_data_p): Overhaul this function to take into
>> 	consideration the value given via G option.
>> 	(arc_rewrite_small_data_1): Renamed and corrected old
>> 	arc_rewrite_small_data function.
>> 	(arc_rewrite_small_data): New function.
>> 	(small_data_pattern): Don't use pic_offset_table_rtx.
>> 	* config/arc/arc.h (CC1_SPEC): Recognize G option.
>> 	* config/arc/simdext.md (movmisalignv2hi): Use
>> 	prepare_move_operands function.
>> 	(mov*): Likewise.
>> 	(movmisalign*): Likewise.
>>
>> gcc/testsuite/
>> 2017-04-24  Claudiu Zissulescu  <claziss@synopsys.com>
>>
>> 	* gcc.target/arc/sdata-5.c: New test.
>> 	* gcc.target/arc/arc700-stld-hazard.c: Update test options.
>
>  From looking at other targets, I think that we need to add
> documentation for -G into the ARC Options section of of
> gcc/doc/invoke.texi.

Yes.  It would probably be better to treat -G as a target-independent 
option enabled by some target hook and consolidate the documentation as 
well, but since it's not done that way at present there needs to be an 
entry for -G in the ARC options table.

-Sandra
Claudiu Zissulescu Aug. 31, 2017, 2:29 p.m. UTC | #3
> From looking at other targets, I think that we need to add
> documentation for -G into the ARC Options section of of
> gcc/doc/invoke.texi.

Added to invoke.texi as suggested.


> Is it critical that we rely on default types here?  I know it's
> legitimate, but it just makes me sad to see new code using default
> types.

No, just a small mistake on my side. I've updated the test as suggested.

> 
> Also, I guess that this test expects some things to be placed into the
> small data section? Is there no pattern we can 'scan-assembler' for?
> Or is this testing some other feature / bug?

The test should check the interaction between the small data and data section anchors (which are default when compiling for size). In the case of an issue, we should get an ICE. Anyhow, I've added also a scan-assembler for clarity.

Committed with above changes. Thank you for your review,
Claudiu
diff mbox

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 0518cb7..564d7ff 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -318,7 +318,7 @@  arc*-*-*)
 	cpu_type=arc
 	c_target_objs="arc-c.o"
 	cxx_target_objs="arc-c.o"
-	extra_options="${extra_options} arc/arc-tables.opt"
+	extra_options="${extra_options} arc/arc-tables.opt g.opt"
 	extra_headers="arc-simd.h"
 	;;
 arm*-*-*)
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 091bc89..cf52df8 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -78,26 +78,21 @@  static const char *arc_cpu_string = arc_cpu_name;
 		      ? 0 \
 		      : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
 
-#define LEGITIMATE_SCALED_ADDRESS_P(MODE, X, STRICT) \
-(GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == MULT \
- && RTX_OK_FOR_INDEX_P (XEXP (XEXP (X, 0), 0), (STRICT)) \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
- && ((GET_MODE_SIZE (MODE) == 2 && INTVAL (XEXP (XEXP (X, 0), 1)) == 2) \
-     || (GET_MODE_SIZE (MODE) == 4 && INTVAL (XEXP (XEXP (X, 0), 1)) == 4)) \
- && (RTX_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
-     || (flag_pic ? CONST_INT_P (XEXP (X, 1)) : CONSTANT_P (XEXP (X, 1)))))
-
-#define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
-  (GET_CODE (X) == PLUS \
-   && (REG_P (XEXP ((X), 0)) && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM) \
-   && ((GET_CODE (XEXP((X),1)) == SYMBOL_REF \
-	&& SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
-       || (GET_CODE (XEXP ((X), 1)) == CONST \
-	   && GET_CODE (XEXP (XEXP ((X), 1), 0)) == PLUS \
-	   && GET_CODE (XEXP (XEXP (XEXP ((X), 1), 0), 0)) == SYMBOL_REF \
-	   && SYMBOL_REF_SMALL_P (XEXP (XEXP (XEXP ((X), 1), 0), 0)) \
-	   && GET_CODE (XEXP(XEXP (XEXP ((X), 1), 0), 1)) == CONST_INT)))
+#define LEGITIMATE_SMALL_DATA_OFFSET_P(X)				\
+  (GET_CODE (X) == CONST						\
+   && GET_CODE (XEXP ((X), 0)) == PLUS					\
+   && GET_CODE (XEXP (XEXP ((X), 0), 0)) == SYMBOL_REF			\
+   && SYMBOL_REF_SMALL_P (XEXP (XEXP ((X), 0), 0))			\
+   && GET_CODE (XEXP(XEXP ((X), 0), 1)) == CONST_INT			\
+   && INTVAL (XEXP (XEXP ((X), 0), 1)) <= g_switch_value)
+
+#define LEGITIMATE_SMALL_DATA_ADDRESS_P(X)				\
+  (GET_CODE (X) == PLUS							\
+     && REG_P (XEXP ((X), 0))						\
+     && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM			\
+     && ((GET_CODE (XEXP ((X), 1)) == SYMBOL_REF			\
+	    && SYMBOL_REF_SMALL_P (XEXP ((X), 1)))			\
+	 || LEGITIMATE_SMALL_DATA_OFFSET_P (XEXP ((X), 1))))
 
 /* Array of valid operand punctuation characters.  */
 char arc_punct_chars[256];
@@ -275,6 +270,61 @@  static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
 /* Globally visible information about currently selected cpu.  */
 const arc_cpu_t *arc_selected_cpu;
 
+static bool
+legitimate_scaled_address_p (machine_mode mode, rtx op, bool strict)
+{
+  if (GET_CODE (op) != PLUS)
+    return false;
+
+  if (GET_CODE (XEXP (op, 0)) != MULT)
+    return false;
+
+  /* Check multiplication operands.  */
+  if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op, 0), 0), strict))
+    return false;
+
+  if (!CONST_INT_P (XEXP (XEXP (op, 0), 1)))
+    return false;
+
+  switch (GET_MODE_SIZE (mode))
+    {
+    case 2:
+      if (INTVAL (XEXP (XEXP (op, 0), 1)) != 2)
+	return false;
+      break;
+    case 8:
+      if (!TARGET_LL64)
+	return false;
+      /*  Fall through. */
+    case 4:
+      if (INTVAL (XEXP (XEXP (op, 0), 1)) != 4)
+	return false;
+    default:
+      return false;
+    }
+
+  /* Check the base.  */
+  if (RTX_OK_FOR_BASE_P (XEXP (op, 1), (strict)))
+    return true;
+
+  if (flag_pic)
+    {
+      if (CONST_INT_P (XEXP (op, 1)))
+	return true;
+      return false;
+    }
+  if (CONSTANT_P (XEXP (op, 1)))
+    {
+      /* Scalled addresses for sdata is done other places.  */
+      if (GET_CODE (XEXP (op, 1)) == SYMBOL_REF
+	  && SYMBOL_REF_SMALL_P (XEXP (op, 1)))
+	return false;
+      return true;
+    }
+
+  return false;
+}
+
 /* Check for constructions like REG + OFFS, where OFFS can be a
    register, an immediate or an long immediate. */
 
@@ -301,8 +351,7 @@  legitimate_offset_address_p (enum machine_mode mode, rtx x, bool index,
       && (GET_MODE_SIZE (mode) <= 4)
       /* Avoid small data which ends in something like GP +
 	 symb@sda.  */
-      && (!SYMBOL_REF_SMALL_P (XEXP (x, 1))
-	  || TARGET_NO_SDATA_SET))
+      && (!SYMBOL_REF_SMALL_P (XEXP (x, 1))))
     return true;
 
   return false;
@@ -1120,6 +1169,10 @@  arc_override_options (void)
   if (TARGET_COMPACT_CASESI)
     TARGET_CASE_VECTOR_PC_RELATIVE = 1;
 
+  /* Check for small data option */
+  if (!global_options_set.x_g_switch_value && !TARGET_NO_SDATA_SET)
+    g_switch_value = TARGET_LL64 ? 8 : 4;
+
   /* These need to be done at start up.  It's convenient to do them here.  */
   arc_init ();
 }
@@ -5518,7 +5571,7 @@  arc_legitimize_pic_address (rtx orig, rtx oldx)
 
 /* Output address constant X to FILE, taking PIC into account.  */
 
-void
+static void
 arc_output_pic_addr_const (FILE * file, rtx x, int code)
 {
   char buf[256];
@@ -5967,7 +6020,7 @@  arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
      return true;
   if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict))
      return true;
-  if (LEGITIMATE_SCALED_ADDRESS_P (mode, x, strict))
+  if (legitimate_scaled_address_p (mode, x, strict))
     return true;
   if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x))
      return true;
@@ -7561,28 +7614,6 @@  valid_brcc_with_delay_p (rtx *operands)
   return brcc_nolimm_operator (operands[0], VOIDmode);
 }
 
-/* ??? Hack.  This should no really be here.  See PR32143.  */
-static bool
-arc_decl_anon_ns_mem_p (const_tree decl)
-{
-  while (1)
-    {
-      if (decl == NULL_TREE || decl == error_mark_node)
-	return false;
-      if (TREE_CODE (decl) == NAMESPACE_DECL
-	  && DECL_NAME (decl) == NULL_TREE)
-	return true;
-      /* Classes and namespaces inside anonymous namespaces have
-	 TREE_PUBLIC == 0, so we can shortcut the search.  */
-      else if (TYPE_P (decl))
-	return (TREE_PUBLIC (TYPE_NAME (decl)) == 0);
-      else if (TREE_CODE (decl) == NAMESPACE_DECL)
-	return (TREE_PUBLIC (decl) == 0);
-      else
-	decl = DECL_CONTEXT (decl);
-    }
-}
-
 /* Implement TARGET_IN_SMALL_DATA_P.  Return true if it would be safe to
    access DECL using %gp_rel(...)($gp).  */
 
@@ -7591,60 +7622,43 @@  arc_in_small_data_p (const_tree decl)
 {
   HOST_WIDE_INT size;
 
-  /* Strings and functions are never in small data area.  */
-  if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
+  /* Only variables are going into small data area.  */
+  if (TREE_CODE (decl) != VAR_DECL)
     return false;
 
   if (TARGET_NO_SDATA_SET)
     return false;
 
-  if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
-    {
-      const char *name;
-
-      /* Reject anything that isn't in a known small-data section.  */
-      name = DECL_SECTION_NAME (decl);
-      if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
-	return false;
-
-      /* If a symbol is defined externally, the assembler will use the
-	 usual -G rules when deciding how to implement macros.  */
-      if (!DECL_EXTERNAL (decl))
-	  return true;
-    }
-  /* Only global variables go into sdata section for now.  */
-  else
-    {
-      /* Don't put constants into the small data section: we want them
-	 to be in ROM rather than RAM.  */
-      if (TREE_CODE (decl) != VAR_DECL)
-	return false;
-
-      if (TREE_READONLY (decl)
-	  && !TREE_SIDE_EFFECTS (decl)
-	  && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
-	return false;
-
-      /* TREE_PUBLIC might change after the first call, because of the patch
-	 for PR19238.  */
-      if (default_binds_local_p_1 (decl, 1)
-	  || arc_decl_anon_ns_mem_p (decl))
-	return false;
-
-      /* To ensure -mvolatile-cache works
-	 ld.di does not have a gp-relative variant.  */
-      if (TREE_THIS_VOLATILE (decl))
-	return false;
-    }
-
   /* Disable sdata references to weak variables.  */
   if (DECL_WEAK (decl))
     return false;
 
-  size = int_size_in_bytes (TREE_TYPE (decl));
+  /* Don't put constants into the small data section: we want them to
+     be in ROM rather than RAM.  */
+  if (TREE_READONLY (decl))
+    return false;
+
+  /* To ensure -mvolatile-cache works ld.di does not have a
+     gp-relative variant.  */
+  if (!TARGET_VOLATILE_CACHE_SET
+      && TREE_THIS_VOLATILE (decl))
+    return false;
 
-  /* Allow only <=4B long data types into sdata.  */
-  return (size > 0 && size <= 4);
+  if (DECL_SECTION_NAME (decl) != 0)
+    {
+      const char *name = DECL_SECTION_NAME (decl);
+      if (strcmp (name, ".sdata") == 0
+	  || strcmp (name, ".sbss") == 0)
+	return true;
+    }
+  /* If it's not public, there's no need to put it in the small data
+     section.  */
+  else if (TREE_PUBLIC (decl))
+    {
+      size = int_size_in_bytes (TREE_TYPE (decl));
+      return (size > 0 && size <= g_switch_value);
+    }
+  return false;
 }
 
 /* Return true if X is a small data address that can be rewritten
@@ -7673,9 +7687,10 @@  arc_rewrite_small_data_p (const_rtx x)
 /* If possible, rewrite OP so that it refers to small data using
    explicit relocations.  */
 
-rtx
-arc_rewrite_small_data (rtx op)
+static rtx
+arc_rewrite_small_data_1 (rtx op)
 {
+  rtx rgp = gen_rtx_REG (Pmode, SDATA_BASE_REGNUM);
   op = copy_insn (op);
   subrtx_ptr_iterator::array_type array;
   FOR_EACH_SUBRTX_PTR (iter, array, &op, ALL)
@@ -7683,28 +7698,33 @@  arc_rewrite_small_data (rtx op)
       rtx *loc = *iter;
       if (arc_rewrite_small_data_p (*loc))
 	{
-	  gcc_assert (SDATA_BASE_REGNUM == PIC_OFFSET_TABLE_REGNUM);
-	  *loc = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, *loc);
-	  if (loc != &op)
-	    {
-	      if (GET_CODE (op) == MEM && &XEXP (op, 0) == loc)
-		; /* OK.  */
-	      else if (GET_CODE (op) == MEM
-		       && GET_CODE (XEXP (op, 0)) == PLUS
-		       && GET_CODE (XEXP (XEXP (op, 0), 0)) == MULT)
-		*loc = force_reg (Pmode, *loc);
-	      else
-		gcc_unreachable ();
-	    }
+	  *loc = gen_rtx_PLUS (Pmode, rgp, *loc);
 	  iter.skip_subrtxes ();
 	}
       else if (GET_CODE (*loc) == PLUS
-	       && rtx_equal_p (XEXP (*loc, 0), pic_offset_table_rtx))
+	       && rtx_equal_p (XEXP (*loc, 0), rgp))
 	iter.skip_subrtxes ();
     }
   return op;
 }
 
+rtx
+arc_rewrite_small_data (rtx op)
+{
+  op = arc_rewrite_small_data_1 (op);
+
+  /* Check if we fit small data constraints.  */
+  if (MEM_P (op)
+      && !LEGITIMATE_SMALL_DATA_ADDRESS_P (XEXP (op, 0)))
+    {
+      rtx addr = XEXP (op, 0);
+      rtx tmp = gen_reg_rtx (Pmode);
+      emit_move_insn (tmp, addr);
+      op = replace_equiv_address_nv (op, tmp);
+    }
+  return op;
+}
+
 /* Return true if OP refers to small data symbols directly, not through
    a PLUS.  */
 
@@ -7713,12 +7733,14 @@  small_data_pattern (rtx op, machine_mode)
 {
   if (GET_CODE (op) == SEQUENCE)
     return false;
+
+  rtx rgp = gen_rtx_REG (Pmode, SDATA_BASE_REGNUM);
   subrtx_iterator::array_type array;
   FOR_EACH_SUBRTX (iter, array, op, ALL)
     {
       const_rtx x = *iter;
       if (GET_CODE (x) == PLUS
-	  && rtx_equal_p (XEXP (x, 0), pic_offset_table_rtx))
+	  && rtx_equal_p (XEXP (x, 0), rgp))
 	iter.skip_subrtxes ();
       else if (arc_rewrite_small_data_p (x))
 	return true;
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index c7cd798..d4e97cd 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -65,9 +65,9 @@  along with GCC; see the file COPYING3.  If not see
 %(subtarget_cpp_spec)"
 
 #undef CC1_SPEC
-#define CC1_SPEC "\
-%{EB:%{EL:%emay not use both -EB and -EL}} \
-%{EB:-mbig-endian} %{EL:-mlittle-endian} \
+#define CC1_SPEC "%{EB:%{EL:%emay not use both -EB and -EL}}	\
+%{EB:-mbig-endian} %{EL:-mlittle-endian}			\
+%{G*}								\
 "
 extern const char *arc_cpu_to_as (int argc, const char **argv);
 
diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md
index 6c102d3..9f5b4a8 100644
--- a/gcc/config/arc/simdext.md
+++ b/gcc/config/arc/simdext.md
@@ -1383,19 +1383,18 @@ 
  [(set (match_operand:V2HI 0 "general_operand" "")
        (match_operand:V2HI 1 "general_operand" ""))]
  ""
-{
- if (!register_operand (operands[0], V2HImode)
-      && !register_operand (operands[1], V2HImode))
-    operands[1] = force_reg (V2HImode, operands[1]);
-})
+ "{
+   if (prepare_move_operands (operands, V2HImode))
+     DONE;
+  }")
 
 (define_expand "mov<mode>"
   [(set (match_operand:VWH 0 "move_dest_operand" "")
 	(match_operand:VWH 1 "general_operand" ""))]
   ""
   "{
-    if (GET_CODE (operands[0]) == MEM)
-     operands[1] = force_reg (<MODE>mode, operands[1]);
+    if (prepare_move_operands (operands, <MODE>mode))
+     DONE;
    }")
 
 (define_insn_and_split "*mov<mode>_insn"
@@ -1440,11 +1439,10 @@ 
  [(set (match_operand:VWH 0 "general_operand" "")
        (match_operand:VWH 1 "general_operand" ""))]
  ""
-{
- if (!register_operand (operands[0], <MODE>mode)
-      && !register_operand (operands[1], <MODE>mode))
-    operands[1] = force_reg (<MODE>mode, operands[1]);
-})
+ "{
+   if (prepare_move_operands (operands, <MODE>mode))
+     DONE;
+  }")
 
 (define_insn "bswapv2hi2"
   [(set (match_operand:V2HI 0 "register_operand" "=r,r")
diff --git a/gcc/testsuite/gcc.target/arc/arc700-stld-hazard.c b/gcc/testsuite/gcc.target/arc/arc700-stld-hazard.c
index bf6ae33..eba03d8 100644
--- a/gcc/testsuite/gcc.target/arc/arc700-stld-hazard.c
+++ b/gcc/testsuite/gcc.target/arc/arc700-stld-hazard.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-mcpu=arc700" } */
+/* { dg-options "-mcpu=arc700 -mno-sdata" } */
 
 volatile int a;
 volatile int b;
diff --git a/gcc/testsuite/gcc.target/arc/sdata-5.c b/gcc/testsuite/gcc.target/arc/sdata-5.c
new file mode 100755
index 0000000..0fdd52d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/sdata-5.c
@@ -0,0 +1,8 @@ 
+/* { dg-do compile } */
+/* { dg-options "-w -Os" } */
+
+const a[1] = {};
+static short b[] = {};
+
+c;
+fn1() { return a + b[c]; }