aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/arc/arc-protos.h1
-rw-r--r--gcc/config/arc/arc.c71
-rw-r--r--gcc/config/arc/predicates.md7
-rw-r--r--gcc/doc/extend.texi11
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/arc/uncached.c18
7 files changed, 121 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8787d37..0b380db 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index 76b82bf..b469cfc 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 0c98083..624404c 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -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,
diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md
index da20c05..38651f7 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/doc/extend.texi b/gcc/doc/extend.texi
index 5f4e8bb..8eef2a4 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d95175d..9056519 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
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 } } */