Jie Mei <[email protected]> 于2023年5月19日周五 16:07写道:
>
> From: Simon Dardis <[email protected]>
>
> Support for __attribute__ ((code_readable)). Takes up to one argument of
> "yes", "no", "pcrel". This will change the code readability setting for just
> that function. If no argument is supplied, then the setting is 'yes'.
>
> gcc/ChangeLog:
>
> * config/mips/mips.cc (enum mips_code_readable_setting):New enmu.
> (mips_handle_code_readable_attr):New static function.
> (mips_get_code_readable_attr):New static enum function.
> (mips_set_current_function):Set the code_readable mode.
> (mips_option_override):Same as above.
> * doc/extend.texi:Document code_readable.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/mips/code-readable-attr-1.c: New test.
> * gcc.target/mips/code-readable-attr-2.c: New test.
> * gcc.target/mips/code-readable-attr-3.c: New test.
> * gcc.target/mips/code-readable-attr-4.c: New test.
> * gcc.target/mips/code-readable-attr-5.c: New test.
> ---
> gcc/config/mips/mips.cc | 97 ++++++++++++++++++-
> 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, 319 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
>
> diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
> index ca822758b41..97f45e67529 100644
> --- a/gcc/config/mips/mips.cc
> +++ b/gcc/config/mips/mips.cc
> @@ -498,6 +498,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... */
> @@ -602,6 +605,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 *);
> @@ -623,6 +627,8 @@ static const struct attribute_spec mips_attribute_table[]
> = {
> { "micromips", 0, 0, true, false, false, false, NULL, NULL },
> { "nomicromips", 0, 0, true, false, false, false, NULL, NULL },
> { "nocompression", 0, 0, true, false, false, false, NULL, NULL },
> + { "code_readable", 0, 1, true, false, false, false,
> + mips_handle_code_readable_attr, NULL },
> /* Allow functions to be specified as interrupt handlers */
> { "interrupt", 0, 1, false, true, true, false,
> mips_handle_interrupt_attr,
> NULL },
> @@ -1310,6 +1316,81 @@ 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 ATTRIBUTE_UNUSED, tree name,
> + tree args, int flags ATTRIBUTE_UNUSED,
> + bool *no_add_attrs)
> +{
> + 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;
> +}
> +
> +/* Determine the code_readable setting for a function if it has one. Set
> + *valid to true if we have a properly formed argument and
> + return the result. If there's no argument, return GCC's default.
contrib/check_GNU_style.sh complains that one more space is needed after
return the result.
> + Otherwise, leave valid false and return mips_base_code_readable. In
> + that case the result should be unused anyway. */
> +
> +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 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. */
>
> @@ -19905,12 +19986,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
A typo: potientially -> potentially
> + 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. */
> @@ -20042,6 +20136,7 @@ mips_option_override (void)
> were generating uncompressed code. */
> 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 69b21a75e62..b48f5f55513 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -5670,6 +5670,23 @@ command line (@pxref{MIPS Options}).
> This function attribute instructs the compiler to generate a hazard barrier
> return that clears all execution and instruction hazards while returning,
> instead of generating a normal return instruction.
> +
> +@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 00000000000..4ccb27c8bde
> --- /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 00000000000..c7dd5113359
> --- /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 00000000000..99c13a901bc
> --- /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 00000000000..4058ba13810
> --- /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 "\tdla\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 00000000000..0a547a9acfc
> --- /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" } */
> --
> 2.40.1
--
YunQiang Su