summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-12 11:13:40 +0000
committerkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-12 11:13:40 +0000
commitf4252e723d153fa103a07e86408b33bb11b117c2 (patch)
treee1fd6dd4742f53eb6fd1cebe3df42285af729330 /gcc/config
parentb7b4b66a5efa64caca570af16be1f0318a90d0a8 (diff)
downloadgcc-f4252e723d153fa103a07e86408b33bb11b117c2.tar.gz
S/390: Hotpatching fixes.
2015-03-02 Dominik Vogt <vogt@linux.vnet.ibm.com> * config/s390/s390.c (s390_reorg): Move code to output nops after label to s390_reorg (). (s390_asm_output_function_label): Likewise. * config/s390/s390.c (s390_asm_output_function_label): Fix function label alignment with -mhtopatch. * config/s390/s390.md ("unspecv"): New values UNSPECV_NOP_2_BYTE, UNSPECV_NOP_4_BYTE and UNSPECV_NOP_6_BYTE ("nop_2_byte"): New define_insn. ("nop_4_byte"): Likewise. ("nop_6_byte"): Likewise. * doc/extend.texi (hotpatch): hotpatch attribute doc fixes. * doc/invoke.texi (-mhotpatch): -mhotpatch doc fixes. 2015-03-02 Dominik Vogt <vogt@linux.vnet.ibm.com> * gcc.target/s390/hotpatch-21.c: New test for hotpatch alignment. * gcc.target/s390/hotpatch-22.c: Likewise. * gcc.target/s390/hotpatch-23.c: Likewise. * gcc.target/s390/hotpatch-24.c: Likewise. * gcc.target/s390/hotpatch-2.c: Also check hotpatch alignment. * gcc.target/s390/hotpatch-1.c: Update expected output. * gcc.target/s390/hotpatch-2.c: Likewise. * gcc.target/s390/hotpatch-3.c: Likewise. * gcc.target/s390/hotpatch-4.c: Likewise. * gcc.target/s390/hotpatch-5.c: Likewise. * gcc.target/s390/hotpatch-6.c: Likewise. * gcc.target/s390/hotpatch-7.c: Likewise. * gcc.target/s390/hotpatch-8.c: Likewise. * gcc.target/s390/hotpatch-9.c: Likewise. * gcc.target/s390/hotpatch-10.c: Likewise. * gcc.target/s390/hotpatch-11.c: Likewise. * gcc.target/s390/hotpatch-12.c: Likewise. * gcc.target/s390/hotpatch-13.c: Likewise. * gcc.target/s390/hotpatch-14.c: Likewise. * gcc.target/s390/hotpatch-15.c: Likewise. * gcc.target/s390/hotpatch-16.c: Likewise. * gcc.target/s390/hotpatch-17.c: Likewise. * gcc.target/s390/hotpatch-18.c: Likewise. * gcc.target/s390/hotpatch-19.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221381 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/s390/s390.c66
-rw-r--r--gcc/config/s390/s390.md25
2 files changed, 66 insertions, 25 deletions
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 593c0cc8ee2..d2b87046b3a 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -5295,6 +5295,7 @@ s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
if (hotpatch_p)
{
+ unsigned int function_alignment;
int i;
/* Add a trampoline code area before the function label and initialize it
@@ -5308,34 +5309,14 @@ s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
stored directly before the label without crossing a cacheline
boundary. All this is necessary to make sure the trampoline code can
be changed atomically. */
+ function_alignment = MAX (8, DECL_ALIGN (decl) / BITS_PER_UNIT);
+ if (! DECL_USER_ALIGN (decl))
+ function_alignment = MAX (function_alignment,
+ (unsigned int) align_functions);
+ ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (function_alignment));
}
ASM_OUTPUT_LABEL (asm_out_file, fname);
-
- /* Output a series of NOPs after the function label. */
- if (hotpatch_p)
- {
- while (hw_after > 0)
- {
- if (hw_after >= 3 && TARGET_CPU_ZARCH)
- {
- asm_fprintf (asm_out_file, "\tbrcl\t\t0,0\n");
- hw_after -= 3;
- }
- else if (hw_after >= 2)
- {
- gcc_assert (hw_after == 2 || !TARGET_CPU_ZARCH);
- asm_fprintf (asm_out_file, "\tnop\t0\n");
- hw_after -= 2;
- }
- else
- {
- gcc_assert (hw_after == 1);
- asm_fprintf (asm_out_file, "\tnopr\t%%r7\n");
- hw_after -= 1;
- }
- }
- }
}
/* Output machine-dependent UNSPECs occurring in address constant X
@@ -11368,6 +11349,7 @@ static void
s390_reorg (void)
{
bool pool_overflow = false;
+ int hw_before, hw_after;
/* Make sure all splits have been performed; splits after
machine_dependent_reorg might confuse insn length counts. */
@@ -11503,6 +11485,40 @@ s390_reorg (void)
if (insn_added_p)
shorten_branches (get_insns ());
}
+
+ s390_function_num_hotpatch_hw (current_function_decl, &hw_before, &hw_after);
+ if (hw_after > 0)
+ {
+ rtx_insn *insn;
+
+ /* Inject nops for hotpatching. */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG)
+ break;
+ }
+ gcc_assert (insn);
+ /* Output a series of NOPs after the NOTE_INSN_FUNCTION_BEG. */
+ while (hw_after > 0)
+ {
+ if (hw_after >= 3 && TARGET_CPU_ZARCH)
+ {
+ insn = emit_insn_after (gen_nop_6_byte (), insn);
+ hw_after -= 3;
+ }
+ else if (hw_after >= 2)
+ {
+ insn = emit_insn_after (gen_nop_4_byte (), insn);
+ hw_after -= 2;
+ }
+ else
+ {
+ insn = emit_insn_after (gen_nop_2_byte (), insn);
+ hw_after -= 1;
+ }
+ }
+ gcc_assert (hw_after == 0);
+ }
}
/* Return true if INSN is a fp load insn writing register REGNO. */
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index bf698b1cf81..76dca0a68ae 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -153,6 +153,11 @@
UNSPECV_CAS
UNSPECV_ATOMIC_OP
+ ; Hotpatching (unremovable NOPs)
+ UNSPECV_NOP_2_BYTE
+ UNSPECV_NOP_4_BYTE
+ UNSPECV_NOP_6_BYTE
+
; Transactional Execution support
UNSPECV_TBEGIN
UNSPECV_TBEGIN_TDB
@@ -9705,6 +9710,26 @@
"lr\t1,1"
[(set_attr "op_type" "RR")])
+;;- Undeletable nops (used for hotpatching)
+
+(define_insn "nop_2_byte"
+ [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
+ ""
+ "nopr\t%%r7"
+ [(set_attr "op_type" "RR")])
+
+(define_insn "nop_4_byte"
+ [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
+ ""
+ "nop\t0"
+ [(set_attr "op_type" "RX")])
+
+(define_insn "nop_6_byte"
+ [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
+ "TARGET_CPU_ZARCH"
+ "brcl\t0, 0"
+ [(set_attr "op_type" "RIL")])
+
;
; Special literal pool access instruction pattern(s).