From: claziss <claz...@synopsys.com>

Add support for -G option to ARC backend.

gcc/
2017-04-24  Claudiu Zissulescu  <claz...@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  <claz...@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

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]; }
-- 
1.9.1

Reply via email to