diff options
-rw-r--r-- | gcc/c-family/c-common.c | 13 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 4 | ||||
-rw-r--r-- | gcc/doc/tm.texi.in | 2 | ||||
-rw-r--r-- | gcc/final.c | 16 | ||||
-rw-r--r-- | gcc/target.def | 6 | ||||
-rw-r--r-- | gcc/targhooks.c | 17 | ||||
-rw-r--r-- | gcc/targhooks.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/attribute-prolog_pad-1.c | 15 |
8 files changed, 74 insertions, 0 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 9bc02fcf85c..57265c54c97 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -393,6 +393,7 @@ static tree handle_designated_init_attribute (tree *, tree, tree, int, bool *); static tree handle_bnd_variable_size_attribute (tree *, tree, tree, int, bool *); static tree handle_bnd_legacy (tree *, tree, tree, int, bool *); static tree handle_bnd_instrument (tree *, tree, tree, int, bool *); +static tree handle_prolog_pad_attribute (tree *, tree, tree, int, bool *); static void check_function_nonnull (tree, int, tree *); static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT); @@ -833,6 +834,8 @@ const struct attribute_spec c_common_attribute_table[] = handle_bnd_legacy, false }, { "bnd_instrument", 0, 0, true, false, false, handle_bnd_instrument, false }, + { "prolog_pad", 1, 1, false, true, true, + handle_prolog_pad_attribute, false }, { NULL, 0, 0, false, false, false, NULL, false } }; @@ -9663,6 +9666,16 @@ handle_designated_init_attribute (tree *node, tree name, tree, int, return NULL_TREE; } +static tree +handle_prolog_pad_attribute (tree *, tree name, tree, int, + bool *) +{ + warning (OPT_Wattributes, + "%qE attribute is used", name); + + return NULL_TREE; +} + /* Check for valid arguments being passed to a function with FNTYPE. There are NARGS arguments in the array ARGARRAY. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 1ce7181c3d4..9d10b1083c2 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4553,6 +4553,10 @@ will select the smallest suitable mode. This section describes the macros that output function entry (@dfn{prologue}) and exit (@dfn{epilogue}) code. +@deftypefn {Target Hook} void TARGET_ASM_PRINT_PROLOG_PAD (FILE *@var{file}, unsigned HOST_WIDE_INT @var{pad_size}, bool @var{record_p}) +Generate prologue pad +@end deftypefn + @deftypefn {Target Hook} void TARGET_ASM_FUNCTION_PROLOGUE (FILE *@var{file}, HOST_WIDE_INT @var{size}) If defined, a function that outputs the assembler code for entry to a function. The prologue is responsible for setting up the stack frame, diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index a0a0a812fc1..bda6d5c47ce 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3662,6 +3662,8 @@ will select the smallest suitable mode. This section describes the macros that output function entry (@dfn{prologue}) and exit (@dfn{epilogue}) code. +@hook TARGET_ASM_PRINT_PROLOG_PAD + @hook TARGET_ASM_FUNCTION_PROLOGUE @hook TARGET_ASM_FUNCTION_END_PROLOGUE diff --git a/gcc/final.c b/gcc/final.c index 1edc446e3f1..862894f59fc 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1765,6 +1765,22 @@ final_start_function (rtx_insn *first, FILE *file, high_block_linenum = high_function_linenum = last_linenum; + tree prolog_pad_attr + = lookup_attribute ("prolog_pad", TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))); + if (prolog_pad_attr) + { + tree prolog_pad_value = TREE_VALUE (TREE_VALUE (prolog_pad_attr)); + unsigned HOST_WIDE_INT pad_size = 0; + + if (tree_fits_uhwi_p (prolog_pad_value)) + pad_size = tree_to_uhwi (prolog_pad_value); + else + gcc_unreachable (); + + if (pad_size > 0) + targetm.asm_out.print_prolog_pad (file, pad_size, true); + } + if (flag_sanitize & SANITIZE_ADDRESS) asan_function_start (); diff --git a/gcc/target.def b/gcc/target.def index d7543378fe7..63d32854516 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -288,6 +288,12 @@ hidden, protected or internal visibility as specified by @var{visibility}.", void, (tree decl, int visibility), default_assemble_visibility) +DEFHOOK +(print_prolog_pad, + "Generate prologue pad", + void, (FILE *file, unsigned HOST_WIDE_INT pad_size, bool record_p), + default_print_prolog_pad) + /* Output the assembler code for entry to a function. */ DEFHOOK (function_prologue, diff --git a/gcc/targhooks.c b/gcc/targhooks.c index dcf08631c40..fbe0f40a860 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1499,6 +1499,23 @@ default_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size, return move_by_pieces_ninsns (size, alignment, max_size + 1) < ratio; } +void +default_print_prolog_pad (FILE *file, unsigned HOST_WIDE_INT pad_size, + bool record_p) +{ + if (record_p) + fprintf (file, "1:"); + for (int i = 0; i < pad_size; ++i) + fprintf (file, "\tnop\n"); + if (record_p) + { + fprintf (file, "\t.section __prolog_pads_loc, \"a\",@progbits\n"); + fprintf (file, "\t.quad 1b\n"); + fprintf (file, "\t.long %u\n", pad_size); + fprintf (file, "\t.previous\n"); + } +} + bool default_profile_before_prologue (void) { diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 47b5cfc3b8b..d03f9930807 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -199,6 +199,7 @@ extern bool default_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT, enum by_pieces_operation, bool); +extern void default_print_prolog_pad (FILE *, unsigned HOST_WIDE_INT , bool); extern bool default_profile_before_prologue (void); extern reg_class_t default_preferred_reload_class (rtx, reg_class_t); extern reg_class_t default_preferred_output_reload_class (rtx, reg_class_t); diff --git a/gcc/testsuite/c-c++-common/attribute-prolog_pad-1.c b/gcc/testsuite/c-c++-common/attribute-prolog_pad-1.c new file mode 100644 index 00000000000..7404dc546ce --- /dev/null +++ b/gcc/testsuite/c-c++-common/attribute-prolog_pad-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +void f1(void) __attribute__((prolog_pad(1))); +void f2(void) __attribute__((prolog_pad(2))); + +void +f1 (void) +{ + f2 (); +} + +void f2 (void) +{ + f1 (); +} |