Message ID | 1509625835-22344-6-git-send-email-claziss@synopsys.com |
---|---|
State | New |
Headers | show |
Series | New baremetal features and fixes | expand |
On 11/02/2017 06:30 AM, Claudiu Zissulescu wrote: > 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. I see no documentation here. -Sandra
> > I see no documentation here. > Ups, forgot this one :) Please find it attached. I'll merge it into the final patch when everything is approved. Thanks, Claudiu
On 11/03/2017 05:22 AM, Claudiu Zissulescu wrote: >> >> I see no documentation here. >> > > Ups, forgot this one :) Please find it attached. I'll merge it into the final patch when everything is approved. > > Thanks, > Claudiu > > +@node ARC Type Attributes > +@subsection ARC Type Attributes > + > +@cindex @code{uncached} type attribute, ARC > +Declaring variables @code{uncached} allows you to exclude data-cache Since this is a type attribute and not a variable attribute (I presume to allow accessing objects through a pointer), it would be better to say Declaring objects with the @code{uncached} type attribute allows.... > +participation in load and store operations on those variables without And s/variables/objects/ here too. > +involving the additional semantic implications of volatile. The You probably want @code{volatile} markup here? > +@code{.di} instruction suffix is used for all loads and stores of data > +declared @code{uncached}. > + Otherwise, the description makes sense to me. (In fact, I might eventually want to copy this attribute over to the Nios II backend, too, since it also has similar "io"-variant load/store instructions.) -Sandra
Just for the record, here it is the updated documentation as suggested. And, indeed the description may very well be suited for NIOS io-variant as well. Thank you Sandra, Claudiu --- gcc/doc/extend.texi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index a7a770f..3243494 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -6728,6 +6728,7 @@ attributes. @menu * Common Type Attributes:: +* ARC Type Attributes:: * ARM Type Attributes:: * MeP Type Attributes:: * PowerPC Type Attributes:: @@ -7161,6 +7162,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
* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2017-11-02 13:30:34 +0100]: > 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> Looks good, with the updated documentation. Thanks, Andrew > > * 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 >
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 } } */
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