* Claudiu Zissulescu <claudiu.zissule...@synopsys.com> [2017-07-24 10:42:53 
+0200]:

> From: Claudiu Zissulescu <claz...@gmail.com>
> 
> Add alignment check for short load/store instructions used for sdata,
> as they request 32-bit aligned short immediate.  Use sdata symbol
> alignment information and emit scalled loads/stores whenever is
> possible. The scalled address will extend the access range for sdata
> symbols.  Allow 64-bit datum into small data section, if double
> load/store instructions are present.
> 
> gcc/
> 2017-04-12  Claudiu Zissulescu  <claz...@synopsys.com>
> 
>       * config/arc/arc-protos.h (compact_sda_memory_operand): Update
>       prototype.
>       * config/arc/arc.c (arc_print_operand): Output scalled address for
>       sdata whenever is possible.
>       (arc_in_small_data_p): Allow sdata for 64bit datum when double
>       load/stores are available.
>       (compact_sda_memory_operand): Check for the alignment required by
>       code density instructions.
>       * config/arc/arc.md (movsi_insn): Use newly introduced Us0
>       constraint.
>       * config/arc/constraints.md (Usd): Update constraint.
>       (Us0): New constraint.
>       (Usc): Update constraint.
> 
> gcc/testsuite/
> 2017-04-12  Claudiu Zissulescu  <claz...@synopsys.com>
> 
>       * gcc.target/arc/sdata-3.c: New file.

Remember to add both new testsuite files in the ChangeLog, but
otherwise looks good.

Thanks,
Andrew





> ---
>  gcc/config/arc/arc-protos.h            |  2 +-
>  gcc/config/arc/arc.c                   | 64 
> +++++++++++++++++++++++++++++-----
>  gcc/config/arc/constraints.md          |  4 +--
>  gcc/testsuite/gcc.target/arc/sdata-3.c | 32 +++++++++++++++++
>  gcc/testsuite/gcc.target/arc/sdata-4.c | 15 ++++++++
>  5 files changed, 105 insertions(+), 12 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arc/sdata-3.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/sdata-4.c
> 
> diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
> index 850795a..c831972 100644
> --- a/gcc/config/arc/arc-protos.h
> +++ b/gcc/config/arc/arc-protos.h
> @@ -27,7 +27,7 @@ extern struct rtx_def *gen_compare_reg (rtx, machine_mode);
>  /* Declarations for various fns used in the .md file.  */
>  extern void arc_output_function_epilogue (FILE *, HOST_WIDE_INT, int);
>  extern const char *output_shift (rtx *);
> -extern bool compact_sda_memory_operand (rtx op,machine_mode  mode);
> +extern bool compact_sda_memory_operand (rtx, machine_mode, bool);
>  extern bool arc_double_limm_p (rtx);
>  extern void arc_print_operand (FILE *, rtx, int);
>  extern void arc_print_operand_address (FILE *, rtx);
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index 89de6cd..091bc89 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -3900,6 +3900,26 @@ arc_print_operand (FILE *file, rtx x, int code)
>                 fputs (".as", file);
>                 output_scaled = 1;
>               }
> +           else if (LEGITIMATE_SMALL_DATA_ADDRESS_P (addr)
> +                    && GET_MODE_SIZE (GET_MODE (x)) > 1)
> +             {
> +               tree decl = NULL_TREE;
> +               int align = 0;
> +               if (GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
> +                 decl = SYMBOL_REF_DECL (XEXP (addr, 1));
> +               else if (GET_CODE (XEXP (XEXP (XEXP (addr, 1), 0), 0))
> +                        == SYMBOL_REF)
> +                 decl = SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr, 1), 0), 0));
> +               if (decl)
> +                 align = DECL_ALIGN (decl);
> +               align = align / BITS_PER_UNIT;
> +               if ((GET_MODE_SIZE (GET_MODE (x)) == 2)
> +                   && align && ((align & 1) == 0))
> +                 fputs (".as", file);
> +               if ((GET_MODE_SIZE (GET_MODE (x)) >= 4)
> +                   && align && ((align & 3) == 0))
> +                 fputs (".as", file);
> +             }
>             break;
>           case REG:
>             break;
> @@ -7571,12 +7591,10 @@ arc_in_small_data_p (const_tree decl)
>  {
>    HOST_WIDE_INT size;
>  
> +  /* Strings and functions are never in small data area.  */
>    if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
>      return false;
>  
> -
> -  /* We don't yet generate small-data references for -mabicalls.  See related
> -     -G handling in override_options.  */
>    if (TARGET_NO_SDATA_SET)
>      return false;
>  
> @@ -7595,7 +7613,7 @@ arc_in_small_data_p (const_tree decl)
>         return true;
>      }
>    /* Only global variables go into sdata section for now.  */
> -  else if (1)
> +  else
>      {
>        /* Don't put constants into the small data section: we want them
>        to be in ROM rather than RAM.  */
> @@ -7625,9 +7643,6 @@ arc_in_small_data_p (const_tree decl)
>  
>    size = int_size_in_bytes (TREE_TYPE (decl));
>  
> -/*   if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
> -/*     return false; */
> -
>    /* Allow only <=4B long data types into sdata.  */
>    return (size > 0 && size <= 4);
>  }
> @@ -7719,10 +7734,13 @@ small_data_pattern (rtx op, machine_mode)
>  /* volatile cache option still to be handled.  */
>  
>  bool
> -compact_sda_memory_operand (rtx op, machine_mode mode)
> +compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
>  {
>    rtx addr;
>    int size;
> +  tree decl = NULL_TREE;
> +  int align = 0;
> +  int mask = 0;
>  
>    /* Eliminate non-memory operations.  */
>    if (GET_CODE (op) != MEM)
> @@ -7740,7 +7758,35 @@ compact_sda_memory_operand (rtx op, machine_mode mode)
>    /* Decode the address now.  */
>    addr = XEXP (op, 0);
>  
> -  return LEGITIMATE_SMALL_DATA_ADDRESS_P  (addr);
> +  if (!LEGITIMATE_SMALL_DATA_ADDRESS_P (addr))
> +    return false;
> +
> +  if (!short_p || size == 1)
> +    return true;
> +
> +  /* Now check for the alignment, the short loads using gp require the
> +     addresses to be aligned.  */
> +  if (GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
> +    decl = SYMBOL_REF_DECL (XEXP (addr, 1));
> +  else if (GET_CODE (XEXP (XEXP (XEXP (addr, 1), 0), 0)) == SYMBOL_REF)
> +    decl = SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr, 1), 0), 0));
> +  if (decl)
> +    align = DECL_ALIGN (decl);
> +  align = align / BITS_PER_UNIT;
> +
> +  switch (mode)
> +    {
> +    case HImode:
> +      mask = 1;
> +      break;
> +    default:
> +      mask = 3;
> +      break;
> +    }
> +
> +  if (align && ((align & mask) == 0))
> +    return true;
> +  return false;
>  }
>  
>  /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL.  */
> diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
> index 6620daf..0ad318c 100644
> --- a/gcc/config/arc/constraints.md
> +++ b/gcc/config/arc/constraints.md
> @@ -355,7 +355,7 @@
>     "@internal
>      A valid _small-data_ memory operand for ARCompact instructions"
>     (and (match_code "mem")
> -     (match_test "compact_sda_memory_operand (op, VOIDmode)")))
> +     (match_test "compact_sda_memory_operand (op, VOIDmode, true)")))
>  
>  (define_memory_constraint "Usc"
>    "@internal
> @@ -363,7 +363,7 @@
>    (and (match_code "mem")
>         (match_test "!CONSTANT_P (XEXP (op,0))")
>  ;; ??? the assembler rejects stores of immediates to small data.
> -       (match_test "!compact_sda_memory_operand (op, VOIDmode)")))
> +       (match_test "!compact_sda_memory_operand (op, VOIDmode, false)")))
>  
>  (define_constraint "Us<"
>    "@internal
> diff --git a/gcc/testsuite/gcc.target/arc/sdata-3.c 
> b/gcc/testsuite/gcc.target/arc/sdata-3.c
> new file mode 100644
> index 0000000..cdf3b6d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/sdata-3.c
> @@ -0,0 +1,32 @@
> +/* Check if sdata access is done correctly, specially
> +   for variables which are having a different alignment
> +   than the default data type indicates.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +int g_a __attribute__ ((aligned (1)));
> +int g_b;
> +short g_c;
> +char g_d;
> +
> +#define TEST(name, optype)                   \
> +  void test_ ## name (optype x)                      \
> +  {                                          \
> +    g_ ## name += x;                         \
> +  }
> +
> +TEST (a, int)
> +TEST (b, int)
> +TEST (c, short)
> +TEST (d, char)
> +
> +/* { dg-final { scan-assembler "ld r2,\\\[gp,@g_a@sda\\\]" } } */
> +/* { dg-final { scan-assembler "ld.as r2,\\\[gp,@g_b@sda\\\]" } } */
> +/* { dg-final { scan-assembler "ld\[hw\]\\\.as r2,\\\[gp,@g_c@sda\\\]" } } */
> +/* { dg-final { scan-assembler "ldb r2,\\\[gp,@g_d@sda\\\]" } } */
> +
> +/* { dg-final { scan-assembler "st r0,\\\[gp,@g_a@sda\\\]" } } */
> +/* { dg-final { scan-assembler "st_s r0,\\\[gp,@g_b@sda\\\]" { target { 
> arcem || archs } } } } */
> +/* { dg-final { scan-assembler "st\\\.as r0,\\\[gp,@g_b@sda\\\]" { target { 
> arc700 || arc6xx } } } } */
> +/* { dg-final { scan-assembler "st\[hw\]\\\.as r0,\\\[gp,@g_c@sda\\\]" } } */
> +/* { dg-final { scan-assembler "stb r0,\\\[gp,@g_d@sda\\\]" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/sdata-4.c 
> b/gcc/testsuite/gcc.target/arc/sdata-4.c
> new file mode 100644
> index 0000000..45fe712
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/sdata-4.c
> @@ -0,0 +1,15 @@
> +/* Check if sdata access is done correctly, specially
> +   for variables which are having a different alignment
> +   than the default data type indicates.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +short gA  __attribute__ ((aligned(1)));
> +
> +void foo (void)
> +{
> +  gA += gA + 3;
> +}
> +
> +/* { dg-final { scan-assembler-not "ld\[wh\]_s r0,\\\[gp" } } */
> +/* { dg-final { scan-assembler-not "st\[wh\]\\\.as.*gp" } } */
> -- 
> 1.9.1
> 

Reply via email to