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]

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


* 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
> 


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