diff mbox

[MIPS] Add support for code_readable function attribute

Message ID B5E67142681B53468FAF6B7C313565624F4EDC9F@hhmail02.hh.imgtec.org
State New
Headers show

Commit Message

Robert Suchanek May 24, 2016, 2:25 p.m. UTC
Hi,

The patch adds support for __attribute__ ((code_readable)) with
optional argument that accepts `no', `yes' or `pcrel' just
like the -mcode-readable= command line switch.  If the argument
is not specified then the default `yes' is applied.

This of course has only effect on targets supporting -mcode-readable=.

Regards,
Robert

2016-05-24  Matthew Fortune  <matthew.fortune@imgtec.com>
            Simon Dardis  <simon.dardis@imgtec.com>

gcc/
	* config/mips/mips.c (mips_base_code_readable): New.
	(mips_handle_code_readable_attr): New static function.
	(mips_get_code_readable_attr): Likewise.
	(mips_set_current_function): Add support for the code_readable
	attribute.
	(mips_option_override): Likewise.
	* doc/extend.text: Document the new attribute.

gcc/testsuite/
	* gcc.target/mips/code-readable-attr-1.c: New test.
	* gcc.target/mips/code-readable-attr-2.c: Ditto.
	* gcc.target/mips/code-readable-attr-3.c: Ditto.
	* gcc.target/mips/code-readable-attr-4.c: Ditto.
	* gcc.target/mips/code-readable-attr-5.c: Ditto.
---
 gcc/config/mips/mips.c                             | 94 +++++++++++++++++++++-
 gcc/doc/extend.texi                                | 17 ++++
 .../gcc.target/mips/code-readable-attr-1.c         | 51 ++++++++++++
 .../gcc.target/mips/code-readable-attr-2.c         | 49 +++++++++++
 .../gcc.target/mips/code-readable-attr-3.c         | 50 ++++++++++++
 .../gcc.target/mips/code-readable-attr-4.c         | 51 ++++++++++++
 .../gcc.target/mips/code-readable-attr-5.c         |  5 ++
 7 files changed, 316 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/code-readable-attr-1.c
 create mode 100644 gcc/testsuite/gcc.target/mips/code-readable-attr-2.c
 create mode 100644 gcc/testsuite/gcc.target/mips/code-readable-attr-3.c
 create mode 100644 gcc/testsuite/gcc.target/mips/code-readable-attr-4.c
 create mode 100644 gcc/testsuite/gcc.target/mips/code-readable-attr-5.c

Comments

Sandra Loosemore May 25, 2016, 1:45 a.m. UTC | #1
On 05/24/2016 08:25 AM, Robert Suchanek wrote:
> [snip]
>
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index e4d6c1c..dd23c70 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -4441,6 +4441,23 @@ On MIPS targets, you can use the @code{nocompression} function attribute
>   to locally turn off MIPS16 and microMIPS code generation.  This attribute
>   overrides the @option{-mips16} and @option{-mmicromips} options on the
>   command line (@pxref{MIPS Options}).
> +
> +@item code_readable
> +@cindex @code{code_readable} function attribute, MIPS
> +For MIPS targets that support PC-relative addressing modes, this attribute
> +can be used to control how an object is addressed.  The attribute takes
> +a single optional argument:

The problem here is that we don't tell users that the argument has to be 
a string constant in quotes, and not just a token.

How about changing the above text to end with:

"...a single optional argument, which must be one of the following 
string constants:"

and then changing this to be @table @code and quoting the @item strings:

> +
> +@table @samp
> +@item no
> +The function should not read the instruction stream as data.
> +@item yes
> +The function can read the instruction stream as data.
> +@item pcrel
> +The function can read the instruction stream in a pc-relative mode.
> +@end table
> +

Then it'll be consistent with this:

> +If there is no argument supplied, the default of @code{"yes"} applies.
>   @end table
>
>   @node MSP430 Function Attributes

-Sandra
Robert Suchanek May 25, 2016, 7:28 a.m. UTC | #2
Hi Sandra,

> > +@item code_readable
> > +@cindex @code{code_readable} function attribute, MIPS
> > +For MIPS targets that support PC-relative addressing modes, this attribute
> > +can be used to control how an object is addressed.  The attribute takes
> > +a single optional argument:
> 
> The problem here is that we don't tell users that the argument has to be
> a string constant in quotes, and not just a token.
> 
> How about changing the above text to end with:
> 
> "...a single optional argument, which must be one of the following
> string constants:"

Indeed.  I'll include this change.

> 
> and then changing this to be @table @code and quoting the @item strings:

Likewise.

Regards,
Robert
diff mbox

Patch

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 24d98fe..6a469a2 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -492,6 +492,9 @@  static int mips_base_target_flags;
 /* The default compression mode.  */
 unsigned int mips_base_compression_flags;
 
+/* The default code readable setting.  */
+enum mips_code_readable_setting mips_base_code_readable;
+
 /* The ambient values of other global variables.  */
 static int mips_base_schedule_insns; /* flag_schedule_insns */
 static int mips_base_reorder_blocks_and_partition; /* flag_reorder... */
@@ -596,6 +599,7 @@  const enum reg_class mips_regno_to_class[FIRST_PSEUDO_REGISTER] = {
   ALL_REGS,	ALL_REGS,	ALL_REGS,	ALL_REGS
 };
 
+static tree mips_handle_code_readable_attr (tree *, tree, tree, int, bool *);
 static tree mips_handle_interrupt_attr (tree *, tree, tree, int, bool *);
 static tree mips_handle_use_shadow_register_set_attr (tree *, tree, tree, int,
 						      bool *);
@@ -616,6 +620,8 @@  static const struct attribute_spec mips_attribute_table[] = {
   { "micromips",   0, 0, true,  false, false, NULL, false },
   { "nomicromips", 0, 0, true,  false, false, NULL, false },
   { "nocompression", 0, 0, true,  false, false, NULL, false },
+  { "code_readable", 0, 1, true,  false, false, mips_handle_code_readable_attr,
+    false },
   /* Allow functions to be specified as interrupt handlers */
   { "interrupt",   0, 1, false, true,  true, mips_handle_interrupt_attr,
     false },
@@ -1296,6 +1302,77 @@  mips_use_debug_exception_return_p (tree type)
 			   TYPE_ATTRIBUTES (type)) != NULL;
 }
 
+/* Verify the arguments to a code_readable attribute.  */
+
+static tree
+mips_handle_code_readable_attr (tree *node, tree name, tree args,
+				int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+  const char * str;
+
+  if (!is_attribute_p ("code_readable", name) || args == NULL)
+    return NULL_TREE;
+
+  if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
+    {
+      warning (OPT_Wattributes,
+	       "%qE attribute requires a string argument", name);
+      *no_add_attrs = true;
+    }
+  else if (strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "no") != 0
+	   && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "pcrel") != 0
+	   && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "yes") != 0)
+    {
+      warning (OPT_Wattributes,
+	       "argument to %qE attribute is neither no, pcrel nor yes", name);
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
+/* Return the code_readable setting for a function if it has one.  If there
+   is no argument or the function does not have the attribute, return GCC's
+   default.  */
+
+static enum mips_code_readable_setting
+mips_get_code_readable_attr (tree decl)
+{
+  tree attr;
+
+  if (decl == NULL)
+    return mips_base_code_readable;
+
+  attr = lookup_attribute ("code_readable", DECL_ATTRIBUTES (decl));
+
+  if (attr != NULL)
+    {
+      if (TREE_VALUE (attr) != NULL_TREE)
+	{
+	  const char * str;
+
+	  str = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
+	  if (strcmp (str, "no") == 0)
+	    return CODE_READABLE_NO;
+	  else if (strcmp (str, "pcrel") == 0)
+	    return CODE_READABLE_PCREL;
+	  else if (strcmp (str, "yes") == 0)
+	    return CODE_READABLE_YES;
+
+	  /* mips_handle_code_readable_attr will have verified that
+	     the arguments are correct before adding the attribute.  */
+	  gcc_unreachable ();
+	}
+
+      /* Just like GCC's default -mcode-readable= setting, the presence of
+	 the code_readable attribute implies that a function can read data
+	 from the instruction stream by default.  */
+      return CODE_READABLE_YES;
+    }
+
+  return mips_base_code_readable;
+}
+
 /* Return the set of compression modes that are explicitly required
    by the attributes in ATTRIBUTES.  */
 
@@ -19441,12 +19518,25 @@  mips_set_compression_mode (unsigned int compression_mode)
 
 /* Implement TARGET_SET_CURRENT_FUNCTION.  Decide whether the current
    function should use the MIPS16 or microMIPS ISA and switch modes
-   accordingly.  */
+   accordingly.  Also set the current code_readable mode.  */
 
 static void
 mips_set_current_function (tree fndecl)
 {
+  enum mips_code_readable_setting old_code_readable = mips_code_readable;
+
   mips_set_compression_mode (mips_get_compress_mode (fndecl));
+
+  mips_code_readable = mips_get_code_readable_attr (fndecl);
+
+  /* Since the mips_code_readable setting has potientially changed, the
+     relocation tables must be reinitialized.  Otherwise GCC will not
+     split symbols for functions that are code_readable ("no") when others
+     are code_readable ("yes") and ICE later on in places such as
+     mips_emit_move.  Ditto for similar paired cases.  It must be restored
+     to its previous state as well.  */
+  if (old_code_readable != mips_code_readable)
+    mips_init_relocs ();
 }
 

 /* Allocate a chunk of memory for per-function machine-dependent data.  */
@@ -19576,6 +19666,8 @@  mips_option_override (void)
   mips_base_compression_flags = TARGET_COMPRESSION;
   target_flags &= ~TARGET_COMPRESSION;
 
+  mips_base_code_readable = mips_code_readable;
+
   /* -mno-float overrides -mhard-float and -msoft-float.  */
   if (TARGET_NO_FLOAT)
     {
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index e4d6c1c..dd23c70 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4441,6 +4441,23 @@  On MIPS targets, you can use the @code{nocompression} function attribute
 to locally turn off MIPS16 and microMIPS code generation.  This attribute
 overrides the @option{-mips16} and @option{-mmicromips} options on the
 command line (@pxref{MIPS Options}).
+
+@item code_readable
+@cindex @code{code_readable} function attribute, MIPS
+For MIPS targets that support PC-relative addressing modes, this attribute
+can be used to control how an object is addressed.  The attribute takes
+a single optional argument:
+
+@table @samp
+@item no
+The function should not read the instruction stream as data.
+@item yes
+The function can read the instruction stream as data.
+@item pcrel
+The function can read the instruction stream in a pc-relative mode.
+@end table
+
+If there is no argument supplied, the default of @code{"yes"} applies.
 @end table
 
 @node MSP430 Function Attributes
diff --git a/gcc/testsuite/gcc.target/mips/code-readable-attr-1.c b/gcc/testsuite/gcc.target/mips/code-readable-attr-1.c
new file mode 100644
index 0000000..4ccb27c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/code-readable-attr-1.c
@@ -0,0 +1,51 @@ 
+/* { dg-options "(-mips16) -mgp32 addressing=absolute" } */
+/* { dg-skip-if ".half requires -O" { *-*-* } { "-O0" } { "" } } */
+
+volatile int x1;
+volatile int x2;
+volatile int x3;
+volatile int x4;
+volatile int x5;
+volatile int x6;
+volatile int x7;
+volatile int x8;
+volatile int x9;
+volatile int x10;
+volatile int x11;
+
+MIPS16 __attribute__ ((code_readable)) int
+foo (int i, volatile int *x)
+{
+  switch (i)
+    {
+    case 1: return x1 + x[0];
+    case 2: return x2 + x[1];
+    case 3: return x3 + x[2];
+    case 4: return x4 + x[3];
+    case 5: return x5 + x[4];
+    case 6: return x6 + x[5];
+    case 7: return x7 + x[6];
+    case 8: return x8 + x[7];
+    case 9: return x9 + x[8];
+    case 10: return x10 + x[9];
+    case 11: return x11 + x[10];
+    default: return 0;
+    }
+}
+
+extern int k[];
+
+MIPS16 __attribute__ ((code_readable)) int *
+bar (void)
+{
+  return k;
+}
+
+/* { dg-final { scan-assembler "\tla\t" } } */
+/* { dg-final { scan-assembler "\t\\.half\t" } } */
+/* { dg-final { scan-assembler-not "%hi\\(\[^)\]*L" } } */
+/* { dg-final { scan-assembler-not "%lo\\(\[^)\]*L" } } */
+
+/* { dg-final { scan-assembler "\t\\.word\tk\n" } } */
+/* { dg-final { scan-assembler-not "%hi\\(k\\)" } } */
+/* { dg-final { scan-assembler-not "%lo\\(k\\)" } } */
diff --git a/gcc/testsuite/gcc.target/mips/code-readable-attr-2.c b/gcc/testsuite/gcc.target/mips/code-readable-attr-2.c
new file mode 100644
index 0000000..c7dd511
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/code-readable-attr-2.c
@@ -0,0 +1,49 @@ 
+/* { dg-options "(-mips16) -mgp32 addressing=absolute" } */
+
+volatile int x1;
+volatile int x2;
+volatile int x3;
+volatile int x4;
+volatile int x5;
+volatile int x6;
+volatile int x7;
+volatile int x8;
+volatile int x9;
+volatile int x10;
+volatile int x11;
+
+MIPS16 __attribute__((code_readable ("pcrel"))) int
+foo (int i, volatile int *x)
+{
+  switch (i)
+    {
+    case 1: return x1 + x[0];
+    case 2: return x2 + x[1];
+    case 3: return x3 + x[2];
+    case 4: return x4 + x[3];
+    case 5: return x5 + x[4];
+    case 6: return x6 + x[5];
+    case 7: return x7 + x[6];
+    case 8: return x8 + x[7];
+    case 9: return x9 + x[8];
+    case 10: return x10 + x[9];
+    case 11: return x11 + x[10];
+    default: return 0;
+    }
+}
+
+extern int k[];
+
+MIPS16 __attribute__((code_readable ("pcrel"))) int *
+bar (void)
+{
+  return k;
+}
+
+/* { dg-final { scan-assembler-not "\tla\t" } } */
+/* { dg-final { scan-assembler-not "\t\\.half\t" } } */
+/* { dg-final { scan-assembler "\t\\.word\t\[^\n\]*L" } } */
+
+/* { dg-final { scan-assembler "\t\\.word\tk\n" } } */
+/* { dg-final { scan-assembler-not "%hi\\(k\\)" } } */
+/* { dg-final { scan-assembler-not "%lo\\(k\\)" } } */
diff --git a/gcc/testsuite/gcc.target/mips/code-readable-attr-3.c b/gcc/testsuite/gcc.target/mips/code-readable-attr-3.c
new file mode 100644
index 0000000..99c13a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/code-readable-attr-3.c
@@ -0,0 +1,50 @@ 
+/* { dg-options "(-mips16) -mgp32 addressing=absolute" } */
+
+volatile int x1;
+volatile int x2;
+volatile int x3;
+volatile int x4;
+volatile int x5;
+volatile int x6;
+volatile int x7;
+volatile int x8;
+volatile int x9;
+volatile int x10;
+volatile int x11;
+
+MIPS16 __attribute__((code_readable ("no"))) int
+foo (int i, volatile int *x)
+{
+  switch (i)
+    {
+    case 1: return x1 + x[0];
+    case 2: return x2 + x[1];
+    case 3: return x3 + x[2];
+    case 4: return x4 + x[3];
+    case 5: return x5 + x[4];
+    case 6: return x6 + x[5];
+    case 7: return x7 + x[6];
+    case 8: return x8 + x[7];
+    case 9: return x9 + x[8];
+    case 10: return x10 + x[9];
+    case 11: return x11 + x[10];
+    default: return 0;
+    }
+}
+
+extern int k[];
+
+MIPS16 __attribute__((code_readable ("no"))) int *
+bar (void)
+{
+  return k;
+}
+
+/* { dg-final { scan-assembler-not "\tla\t" } } */
+/* { dg-final { scan-assembler-not "\t\\.half\t" } } */
+/* { dg-final { scan-assembler "%hi\\(\[^)\]*L" } } */
+/* { dg-final { scan-assembler "%lo\\(\[^)\]*L" } } */
+
+/* { dg-final { scan-assembler-not "\t\\.word\tk\n" } } */
+/* { dg-final { scan-assembler "%hi\\(k\\)" } } */
+/* { dg-final { scan-assembler "%lo\\(k\\)" } } */
diff --git a/gcc/testsuite/gcc.target/mips/code-readable-attr-4.c b/gcc/testsuite/gcc.target/mips/code-readable-attr-4.c
new file mode 100644
index 0000000..9e3baa0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/code-readable-attr-4.c
@@ -0,0 +1,51 @@ 
+/* { dg-options "(-mips16) -mabi=eabi -mgp64" } */
+/* { dg-skip-if ".half requires -O" { *-*-* } { "-O0" } { "" } } */
+
+volatile int x1;
+volatile int x2;
+volatile int x3;
+volatile int x4;
+volatile int x5;
+volatile int x6;
+volatile int x7;
+volatile int x8;
+volatile int x9;
+volatile int x10;
+volatile int x11;
+
+MIPS16 __attribute__((code_readable ("yes"))) int
+foo (int i, volatile int *x)
+{
+  switch (i)
+    {
+    case 1: return x1 + x[0];
+    case 2: return x2 + x[1];
+    case 3: return x3 + x[2];
+    case 4: return x4 + x[3];
+    case 5: return x5 + x[4];
+    case 6: return x6 + x[5];
+    case 7: return x7 + x[6];
+    case 8: return x8 + x[7];
+    case 9: return x9 + x[8];
+    case 10: return x10 + x[9];
+    case 11: return x11 + x[10];
+    default: return 0;
+    }
+}
+
+extern int k[];
+
+MIPS16 __attribute__((code_readable ("yes"))) int *
+bar (void)
+{
+  return k;
+}
+
+/* { dg-final { scan-assembler "\tla\t" } } */
+/* { dg-final { scan-assembler "\t\\.half\t" } } */
+/* { dg-final { scan-assembler-not "%hi\\(\[^)\]*L" } } */
+/* { dg-final { scan-assembler-not "%lo\\(\[^)\]*L" } } */
+
+/* { dg-final { scan-assembler "\t\\.dword\tk\n" } } */
+/* { dg-final { scan-assembler-not "%hi\\(k\\)" } } */
+/* { dg-final { scan-assembler-not "%lo\\(k\\)" } } */
diff --git a/gcc/testsuite/gcc.target/mips/code-readable-attr-5.c b/gcc/testsuite/gcc.target/mips/code-readable-attr-5.c
new file mode 100644
index 0000000..0a547a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/code-readable-attr-5.c
@@ -0,0 +1,5 @@ 
+/* { dg-options "(-mips16) isa_rev<=5" } */
+
+ __attribute__((code_readable ("magic"))) int foo () {} /* { dg-warning "argument to 'code_readable' attribute is neither no, pcrel nor yes" } */
+
+ __attribute__((code_readable (1))) int * bar () {} /* { dg-warning "'code_readable' attribute requires a string argument" } */