Jie Mei <jie....@oss.cipunited.com> 于2023年5月19日周五 16:07写道: > > From: Simon Dardis <simon.dar...@imgtec.com> > > 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