[ARC] Add 'uncached' attribute.
authorClaudiu Zissulescu <claziss@synopsys.com>
Wed, 31 Jan 2018 10:01:34 +0000 (11:01 +0100)
committerClaudiu Zissulescu <claziss@gcc.gnu.org>
Wed, 31 Jan 2018 10:01:34 +0000 (11:01 +0100)
The _Uncached type qualifier can be used to bypass the cache without
resorting to declaring variables as volatile.

gcc/
2018-01-31  Claudiu Zissulescu  <claziss@synopsys.com>

* config/arc/arc-protos.h (arc_is_uncached_mem_p): Function proto.
* config/arc/arc.c (arc_handle_uncached_attribute): New function.
(arc_attribute_table): Add 'uncached' attribute.
(arc_print_operand): Print '.di' flag for uncached memory
accesses.
(arc_in_small_data_p): Do not consider for small data the uncached
types.
(arc_is_uncached_mem_p): New function.
* config/arc/predicates.md (compact_store_memory_operand): Check
for uncached memory accesses.
(nonvol_nonimm_operand): Likewise.
* gcc/doc/extend.texi (ARC Type Attribute): New subsection.

gcc/testsuite
2018-01-31  Claudiu Zissulescu  <claziss@synopsys.com>

* gcc.target/arc/uncached.c: New test.

From-SVN: r257222

gcc/ChangeLog
gcc/config/arc/arc-protos.h
gcc/config/arc/arc.c
gcc/config/arc/predicates.md
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arc/uncached.c [new file with mode: 0644]

index 8787d37c6b737880cb4e71990ed1abb91200e915..0b380db6b52b687c0da177600be20611af723ffc 100644 (file)
@@ -1,3 +1,18 @@
+2018-01-31  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * config/arc/arc-protos.h (arc_is_uncached_mem_p): Function proto.
+       * config/arc/arc.c (arc_handle_uncached_attribute): New function.
+       (arc_attribute_table): Add 'uncached' attribute.
+       (arc_print_operand): Print '.di' flag for uncached memory
+       accesses.
+       (arc_in_small_data_p): Do not consider for small data the uncached
+       types.
+       (arc_is_uncached_mem_p): New function.
+       * config/arc/predicates.md (compact_store_memory_operand): Check
+       for uncached memory accesses.
+       (nonvol_nonimm_operand): Likewise.
+       * gcc/doc/extend.texi (ARC Type Attribute): New subsection.
+
 2018-01-31  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/84100
index 76b82bfb517ae6900e5f577e5affcc02829b998b..b469cfc4c2c870a1939fc8acbd612618681aa626 100644 (file)
@@ -47,6 +47,7 @@ extern void arc_expand_compare_and_swap (rtx *);
 extern bool compact_memory_operand_p (rtx, machine_mode, bool, bool);
 extern int arc_return_address_register (unsigned int);
 extern unsigned int arc_compute_function_type (struct function *);
+extern bool arc_is_uncached_mem_p (rtx);
 #endif /* RTX_CODE */
 
 extern unsigned int arc_compute_frame_size (int);
index 0c98083f37a1bfadc11742e4781b629d8d851468..624404cf35a58d455d885b47507c435eb2f8451c 100644 (file)
@@ -227,7 +227,7 @@ static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *);
-
+static tree arc_handle_uncached_attribute (tree *, tree, tree, int, bool *);
 
 /* Initialized arc_attribute_table to NULL since arc doesnot have any
    machine specific supported attributes.  */
@@ -253,13 +253,16 @@ const struct attribute_spec arc_attribute_table[] =
     NULL },
   /* Functions calls made using jli instruction.  The pointer in JLI
      table is found latter.  */
-  { "jli_always",    0, 0, false, true,  true,  NULL, NULL },
+  { "jli_always",    0, 0, false, true,  true, false,  NULL, NULL },
   /* Functions calls made using jli instruction.  The pointer in JLI
      table is given as input parameter.  */
-  { "jli_fixed",    1, 1, false, true,  true,  arc_handle_jli_attribute,
+  { "jli_fixed",    1, 1, false, true,  true, false, arc_handle_jli_attribute,
     NULL },
   /* Call a function using secure-mode.  */
-  { "secure_call",  1, 1, false, true, true, arc_handle_secure_attribute,
+  { "secure_call",  1, 1, false, true, true, false, arc_handle_secure_attribute,
+    NULL },
+   /* Bypass caches using .di flag.  */
+  { "uncached", 0, 0, false, true, false, false, arc_handle_uncached_attribute,
     NULL },
   { NULL, 0, 0, false, false, false, false, NULL, NULL }
 };
@@ -4193,7 +4196,8 @@ arc_print_operand (FILE *file, rtx x, int code)
         refs are defined to use the cache bypass mechanism.  */
       if (GET_CODE (x) == MEM)
        {
-         if (MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET )
+         if ((MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET)
+             || arc_is_uncached_mem_p (x))
            fputs (".di", file);
        }
       else
@@ -8102,6 +8106,7 @@ static bool
 arc_in_small_data_p (const_tree decl)
 {
   HOST_WIDE_INT size;
+  tree attr;
 
   /* Only variables are going into small data area.  */
   if (TREE_CODE (decl) != VAR_DECL)
@@ -8125,6 +8130,11 @@ arc_in_small_data_p (const_tree decl)
       && TREE_THIS_VOLATILE (decl))
     return false;
 
+  /* Likewise for uncached data.  */
+  attr = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+  if (lookup_attribute ("uncached", attr))
+    return false;
+
   if (DECL_SECTION_NAME (decl) != 0)
     {
       const char *name = DECL_SECTION_NAME (decl);
@@ -11130,6 +11140,57 @@ arc_is_secure_call_p (rtx pat)
   return false;
 }
 
+/* Handle "uncached" qualifier.  */
+
+static tree
+arc_handle_uncached_attribute (tree *node,
+                              tree name, tree args,
+                              int flags ATTRIBUTE_UNUSED,
+                              bool *no_add_attrs)
+{
+  if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL)
+    {
+      error ("%qE attribute only applies to types",
+            name);
+      *no_add_attrs = true;
+    }
+  else if (args)
+    {
+      warning (OPT_Wattributes, "argument of %qE attribute ignored", name);
+    }
+  return NULL_TREE;
+}
+
+/* Return TRUE if PAT is a memory addressing an uncached data.  */
+
+bool
+arc_is_uncached_mem_p (rtx pat)
+{
+  tree attrs;
+  tree ttype;
+  struct mem_attrs *refattrs;
+
+  if (!MEM_P (pat))
+    return false;
+
+  /* Get the memory attributes.  */
+  refattrs = MEM_ATTRS (pat);
+  if (!refattrs
+      || !refattrs->expr)
+    return false;
+
+  /* Get the type declaration.  */
+  ttype = TREE_TYPE (refattrs->expr);
+  if (!ttype)
+    return false;
+
+  /* Get the type attributes.  */
+  attrs = TYPE_ATTRIBUTES (ttype);
+  if (lookup_attribute ("uncached", attrs))
+    return true;
+  return false;
+}
+
 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P.  We don't want to use
    anchors for small data: the GP register acts as an anchor in that
    case.  We also don't want to use them for PC-relative accesses,
index da20c0592339e941a2d5edd733232c25d3f4bd01..38651f79bf43d29fd1eb4a5e02f57fa5127fd627 100644 (file)
   if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
      return 0;
 
+  /* likewise for uncached types.  */
+  if (arc_is_uncached_mem_p (op))
+     return 0;
+
   size = GET_MODE_SIZE (mode);
 
   /* dword operations really put out 2 instructions, so eliminate them.  */
 ;; and only the standard movXX patterns are set up to handle them.
 (define_predicate "nonvol_nonimm_operand"
   (and (match_code "subreg, reg, mem")
-       (match_test "(GET_CODE (op) != MEM || !MEM_VOLATILE_P (op)) && nonimmediate_operand (op, mode)"))
+       (match_test "(GET_CODE (op) != MEM || !MEM_VOLATILE_P (op)) && nonimmediate_operand (op, mode)")
+       (match_test "!arc_is_uncached_mem_p (op)"))
 )
 
 ;; Return 1 if OP is a comparison operator valid for the mode of CC.
index 5f4e8bbc1856f5f1269724e2caf69d67d34549bc..8eef2a492b361a28c476287c69dc1e4f633f3d68 100644 (file)
@@ -6817,6 +6817,7 @@ attributes.
 
 @menu
 * Common Type Attributes::
+* ARC Type Attributes::
 * ARM Type Attributes::
 * MeP Type Attributes::
 * PowerPC Type Attributes::
@@ -7250,6 +7251,16 @@ To specify multiple attributes, separate them by commas within the
 double parentheses: for example, @samp{__attribute__ ((aligned (16),
 packed))}.
 
+@node ARC Type Attributes
+@subsection ARC Type Attributes
+
+@cindex @code{uncached} type attribute, ARC
+Declaring objects with @code{uncached} allows you to exclude
+data-cache participation in load and store operations on those objects
+without involving the additional semantic implications of
+@code{volatile}.  The @code{.di} instruction suffix is used for all
+loads and stores of data declared @code{uncached}.
+
 @node ARM Type Attributes
 @subsection ARM Type Attributes
 
index d95175dd1cb24c76a6d0975482ba35027077b3c9..9056519e8ce008ea4208834c47b367f7beef8f5c 100644 (file)
@@ -1,3 +1,7 @@
+2018-01-31  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * gcc.target/arc/uncached.c: New test.
+
 2018-01-31  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        PR lto/83954
diff --git a/gcc/testsuite/gcc.target/arc/uncached.c b/gcc/testsuite/gcc.target/arc/uncached.c
new file mode 100644 (file)
index 0000000..367e8dc
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+/* Check 'uncached' type attribute.  */
+
+typedef volatile unsigned int RwReg  __attribute__ ((uncached));
+
+typedef struct {
+  RwReg UART_THR;
+  int SIDE_DISH;
+} UART;
+
+void uart_putc(UART *port, char c)
+{
+    port->UART_THR = c;
+    port->SIDE_DISH = c;
+}
+
+/* { dg-final { scan-assembler-times "st\.di" 1 } } */