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. */
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 }
};
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
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)
&& 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);
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,