unsigned short patch_area_size = crtl->patch_area_size;
unsigned short patch_area_entry = crtl->patch_area_entry;
- /* Need to emit the patching area. */
- if (patch_area_size > 0)
+ /* Emit non-split patching area now. */
+ if (!TARGET_SPLIT_PATCH_NOPS && patch_area_size > 0)
{
cfun->machine->global_entry_emitted = true;
/* As ELFv2 ABI shows, the allowable bytes between the global
patch_area_entry);
rs6000_print_patchable_function_entry (file, patch_area_entry,
true);
- patch_area_size -= patch_area_entry;
}
}
assemble_name (file, name);
fputs ("\n", file);
/* Emit the nops after local entry. */
- if (patch_area_size > 0)
- rs6000_print_patchable_function_entry (file, patch_area_size,
- patch_area_entry == 0);
+ if (patch_area_size > patch_area_entry)
+ {
+ patch_area_size -= patch_area_entry;
+ cfun->machine->stop_patch_area_print = false;
+ rs6000_print_patchable_function_entry (file, patch_area_size,
+ patch_area_entry == 0);
+ }
}
else if (rs6000_pcrel_p ())
{
bool global_entry_needed_p = rs6000_global_entry_point_prologue_needed_p ();
/* For a function which needs global entry point, we will emit the
- patchable area before and after local entry point under the control of
- cfun->machine->global_entry_emitted, see the handling in function
- rs6000_output_function_prologue. */
- if (!global_entry_needed_p || cfun->machine->global_entry_emitted)
+ patchable area when it isn't split before and after local entry point
+ under the control of cfun->machine->global_entry_emitted, see the
+ handling in function rs6000_output_function_prologue. */
+ if (!TARGET_SPLIT_PATCH_NOPS
+ && (!global_entry_needed_p || cfun->machine->global_entry_emitted))
default_print_patchable_function_entry (file, patch_area_size, record_p);
+
+ /* For split patch nops we emit the before nops (from generic code)
+ in front of the global entry point and after the local entry point,
+ under the control of cfun->machine->stop_patch_area_print, see
+ rs6000_output_function_prologue and rs6000_elf_declare_function_name. */
+ if (TARGET_SPLIT_PATCH_NOPS)
+ {
+ if (!cfun->machine->stop_patch_area_print)
+ default_print_patchable_function_entry (file, patch_area_size,
+ record_p);
+ else
+ gcc_assert (global_entry_needed_p);
+ }
}
\f
enum rtx_code
fprintf (file, "\t.previous\n");
}
ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
+ /* At this time, the "before" NOPs have been already emitted.
+ For split nops stop generic code from printing the "after" NOPs and
+ emit them just after local entry ourself later. */
+ if (rs6000_global_entry_point_prologue_needed_p ())
+ cfun->machine->stop_patch_area_print = true;
}
static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
local entry. */
bool global_entry_emitted;
bool asm_redzone_clobber_seen;
+ /* With ELFv2 ABI dual entry points being adopted, generic framework
+ targetm.asm_out.print_patchable_function_entry would generate "after"
+ NOPs before local entry, which is wrong. This flag is to stop it from
+ printing patch area before local entry, it is only useful when the
+ function requires dual entry points. */
+ bool stop_patch_area_print;
} machine_function;
#endif
Target
Put everything in the regular TOC.
+msplit-patch-nops
+Target Var(TARGET_SPLIT_PATCH_NOPS) Init(0)
+Emit NOPs before global and after local entry point for -fpatchable-function-entry.
+
mvrsave
Target Var(TARGET_ALTIVEC_VRSAVE) Save
Generate VRSAVE instructions when generating AltiVec code.
-mtraceback=@var{traceback_type}
-maix-struct-return -msvr4-struct-return
-mabi=@var{abi-type} -msecure-plt -mbss-plt
+-msplit-patch-nops
-mlongcall -mno-longcall -mpltseq -mno-pltseq
-mblock-move-inline-limit=@var{num}
-mblock-compare-inline-limit=@var{num}
The NOP instructions are inserted at---and maybe before, depending on
@var{M}---the function entry address, even before the prologue. On
PowerPC with the ELFv2 ABI, for a function with dual entry points,
-the local entry point is this function entry address.
+the local entry point is this function entry address by default. See
+the @option{-msplit-patch-nops} option to change this.
The maximum value of @var{N} and @var{M} is 65535. On PowerPC with the
ELFv2 ABI, for a function with dual entry points, the supported values
-for @var{M} are 0, 2, 6 and 14.
+for @var{M} are 0, 2, 6 and 14 when not using @option{-msplit-patch-nops}.
@end table
sections that are both writable and executable.
This is a PowerPC 32-bit SYSV ABI option.
+@opindex msplit-patch-nops
+@item -msplit-patch-nops
+When adding NOPs for a patchable area via the
+@option{-fpatchable-function-entry} option emit the ``before'' NOPs in front
+of the global entry point and the ``after'' NOPs after the local entry point.
+This makes the sequence of NOPs not consecutive when a global entry point
+is generated. Without this option the NOPs are emitted directly before and
+after the local entry point, making them consecutive but moving global and
+local entry point further apart. If only a single entry point is generated
+this option has no effect.
+
@opindex misel
@opindex mno-isel
@item -misel