This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 5/6] [ARC] Add 'uncached' attribute.


From: claziss <claziss@synopsys.com>

The _Uncached type qualifier can be used to bypass the cache without
resorting to declaring variables as volatile.

gcc/
2017-07-12  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/testsuite
2017-07-12  Claudiu Zissulescu  <claziss@synopsys.com>

	* gcc.target/arc/uncached.c: New test.
---
 gcc/config/arc/arc-protos.h             |  1 +
 gcc/config/arc/arc.c                    | 65 ++++++++++++++++++++++++++++++++-
 gcc/config/arc/predicates.md            |  7 +++-
 gcc/testsuite/gcc.target/arc/uncached.c | 18 +++++++++
 4 files changed, 88 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/uncached.c

diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index f8e7937..cc00730 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -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);
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 07dd072..a397cbd 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -222,7 +222,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.  */
@@ -254,6 +254,9 @@ const struct attribute_spec arc_attribute_table[] =
   /* Call a function using secure-mode.  */
   { "secure_call",  1, 1, false, true, true, arc_handle_secure_attribute,
     false },
+  /* Bypass caches using .di flag.  */
+  { "uncached", 0, 0, false, true, false, arc_handle_uncached_attribute,
+    false },
   { NULL, 0, 0, false, false, false, NULL, false }
 };
 static int arc_comp_type_attributes (const_tree, const_tree);
@@ -4135,7 +4138,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
@@ -8038,6 +8042,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)
@@ -8061,6 +8066,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);
@@ -11066,6 +11076,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,
diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md
index 3dfe0ca..68887be 100644
--- a/gcc/config/arc/predicates.md
+++ b/gcc/config/arc/predicates.md
@@ -217,6 +217,10 @@
   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.  */
@@ -412,7 +416,8 @@
 ;; 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.
diff --git a/gcc/testsuite/gcc.target/arc/uncached.c b/gcc/testsuite/gcc.target/arc/uncached.c
new file mode 100644
index 0000000..367e8dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/uncached.c
@@ -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 } } */
-- 
1.9.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]