aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>2017-06-28 07:03:35 +0000
committerAndreas Krebbel <krebbel@gcc.gnu.org>2017-06-28 07:03:35 +0000
commit935b5226c385e34088c314374cbbe9e4995b9e44 (patch)
tree23d3790403d00862b7e13222615a0f27eeb982cc /gcc
parent8801653208ef13e4762d907971e3a6b83a8e721e (diff)
downloadgcc-935b5226c385e34088c314374cbbe9e4995b9e44.zip
gcc-935b5226c385e34088c314374cbbe9e4995b9e44.tar.gz
gcc-935b5226c385e34088c314374cbbe9e4995b9e44.tar.bz2
S/390: New option -mpic-data-is-text-relative
For hotpatching it might be required to introduce new .text parts while keep using the existing .data/.bss sections. To make this work the backend needs to be prevented from using relative addressing between code and data. This only works when already building PIC since the addressing will then be handling via GOT. gcc/testsuite/ChangeLog: 2017-06-28 Andreas Krebbel <krebbel@linux.vnet.ibm.com> * gcc.target/s390/nodatarel-1.c: New test. gcc/ChangeLog: 2017-06-28 Andreas Krebbel <krebbel@linux.vnet.ibm.com> * config/s390/predicates.md: Use s390_rel_address_ok_p. * config/s390/s390-protos.h: Add prototype of s390_rel_address_ok_p. * config/s390/s390.c (s390_got_symbol): New function. (s390_rel_address_ok_p): New function. (legitimize_pic_address): Use s390_rel_address_ok_p. (s390_load_got): Use s390_got_symbol. (s390_option_override): Issue error if -mno-pic-data-is-text-relative is used without -fpic/-fPIC. * config/s390/s390.h (TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE): New macro. * config/s390/s390.opt: New option mpic-data-is-text-relative. From-SVN: r249720
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/s390/predicates.md9
-rw-r--r--gcc/config/s390/s390-protos.h1
-rw-r--r--gcc/config/s390/s390.c53
-rw-r--r--gcc/config/s390/s390.h4
-rw-r--r--gcc/config/s390/s390.opt4
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/s390/nodatarel-1.c83
8 files changed, 159 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f52d1b9..48c81b3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2017-06-28 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
+ * config/s390/predicates.md: Use s390_rel_address_ok_p.
+ * config/s390/s390-protos.h: Add prototype of
+ s390_rel_address_ok_p.
+ * config/s390/s390.c (s390_got_symbol): New function.
+ (s390_rel_address_ok_p): New function.
+ (legitimize_pic_address): Use s390_rel_address_ok_p.
+ (s390_load_got): Use s390_got_symbol.
+ (s390_option_override): Issue error if
+ -mno-pic-data-is-text-relative is used without -fpic/-fPIC.
+ * config/s390/s390.h (TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE):
+ New macro.
+ * config/s390/s390.opt: New option mpic-data-is-text-relative.
+
2017-06-27 Andrew Pinski <apinski@cavium.com>
* match.pd (X >/>=/</<= 0 ? 1.0 : -1.0): New patterns.
diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index 34a7ea2..fc151ac 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -131,10 +131,10 @@
/* Allow labels and local symbols. */
if (GET_CODE (op) == LABEL_REF)
return true;
- if (GET_CODE (op) == SYMBOL_REF)
+ if (SYMBOL_REF_P (op))
return (!SYMBOL_FLAG_NOTALIGN2_P (op)
&& SYMBOL_REF_TLS_MODEL (op) == 0
- && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
+ && s390_rel_address_ok_p (op));
/* Everything else must have a CONST, so strip it. */
if (GET_CODE (op) != CONST)
@@ -156,10 +156,11 @@
/* Labels and local symbols allowed here as well. */
if (GET_CODE (op) == LABEL_REF)
return true;
- if (GET_CODE (op) == SYMBOL_REF)
+ if (SYMBOL_REF_P (op))
return (!SYMBOL_FLAG_NOTALIGN2_P (op)
&& SYMBOL_REF_TLS_MODEL (op) == 0
- && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
+ && s390_rel_address_ok_p (op));
+
/* Now we must have a @GOTENT offset or @PLT stub
or an @INDNTPOFF TLS offset. */
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 3fdb320..6df37ef 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -79,6 +79,7 @@ extern bool s390_bytemask_vector_p (rtx, unsigned *);
extern bool s390_split_ok_p (rtx, rtx, machine_mode, int);
extern bool s390_overlap_p (rtx, rtx, HOST_WIDE_INT);
extern bool s390_offset_p (rtx, rtx, rtx);
+extern bool s390_rel_address_ok_p (rtx);
extern int tls_symbolic_operand (rtx);
extern bool s390_match_ccmode (rtx_insn *, machine_mode);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index eb94237..bfc38db 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -1179,6 +1179,23 @@ s390_label_align (rtx_insn *label)
return align_labels_log;
}
+static GTY(()) rtx got_symbol;
+
+/* Return the GOT table symbol. The symbol will be created when the
+ function is invoked for the first time. */
+
+static rtx
+s390_got_symbol (void)
+{
+ if (!got_symbol)
+ {
+ got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+ SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
+ }
+
+ return got_symbol;
+}
+
static machine_mode
s390_libgcc_cmp_return_mode (void)
{
@@ -4496,6 +4513,26 @@ s390_load_address (rtx dst, rtx src)
emit_insn (gen_force_la_31 (dst, src));
}
+/* Return true if it ok to use SYMBOL_REF in a relative address. */
+
+bool
+s390_rel_address_ok_p (rtx symbol_ref)
+{
+ tree decl;
+
+ if (symbol_ref == s390_got_symbol () || CONSTANT_POOL_ADDRESS_P (symbol_ref))
+ return true;
+
+ decl = SYMBOL_REF_DECL (symbol_ref);
+
+ if (!flag_pic || SYMBOL_REF_LOCAL_P (symbol_ref))
+ return (s390_pic_data_is_text_relative
+ || (decl
+ && TREE_CODE (decl) == FUNCTION_DECL));
+
+ return false;
+}
+
/* Return a legitimate reference for ORIG (an address) using the
register REG. If REG is 0, a new pseudo is generated.
@@ -4533,7 +4570,7 @@ legitimize_pic_address (rtx orig, rtx reg)
}
if ((GET_CODE (addr) == LABEL_REF
- || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr))
+ || (SYMBOL_REF_P (addr) && s390_rel_address_ok_p (addr))
|| (GET_CODE (addr) == UNSPEC &&
(XINT (addr, 1) == UNSPEC_GOTENT
|| (TARGET_CPU_ZARCH && XINT (addr, 1) == UNSPEC_PLT))))
@@ -10791,7 +10828,6 @@ restore_gprs (rtx base, int offset, int first, int last)
/* Return insn sequence to load the GOT register. */
-static GTY(()) rtx got_symbol;
rtx_insn *
s390_load_got (void)
{
@@ -10803,23 +10839,17 @@ s390_load_got (void)
aren't usable. */
rtx got_rtx = gen_rtx_REG (Pmode, 12);
- if (!got_symbol)
- {
- got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
- SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
- }
-
start_sequence ();
if (TARGET_CPU_ZARCH)
{
- emit_move_insn (got_rtx, got_symbol);
+ emit_move_insn (got_rtx, s390_got_symbol ());
}
else
{
rtx offset;
- offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
+ offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, s390_got_symbol ()),
UNSPEC_LTREL_OFFSET);
offset = gen_rtx_CONST (Pmode, offset);
offset = force_const_mem (Pmode, offset);
@@ -14911,6 +14941,9 @@ s390_option_override (void)
if (flag_prefetch_loop_arrays < 0 && HAVE_prefetch && optimize >= 3)
flag_prefetch_loop_arrays = 1;
+ if (!s390_pic_data_is_text_relative && !flag_pic)
+ error ("-mno-pic-data-is-text-relative cannot be used without -fpic/-fPIC");
+
if (TARGET_TPF)
{
/* Don't emit DWARF3/4 unless specifically selected. The TPF
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index a372981..7847047 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -946,6 +946,10 @@ CUMULATIVE_ARGS;
#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
+#ifndef TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE
+#define TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE 1
+#endif
+
/* Assembler file format. */
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
index d0a0d46..f277ac5 100644
--- a/gcc/config/s390/s390.opt
+++ b/gcc/config/s390/s390.opt
@@ -226,3 +226,7 @@ values are small, non-negative integers. The default branch cost is
mlra
Target Report Var(s390_lra_flag) Init(1) Save
Use LRA instead of reload.
+
+mpic-data-is-text-relative
+Target Report Var(s390_pic_data_is_text_relative) Init(TARGET_DEFAULT_PIC_DATA_IS_TEXT_RELATIVE)
+Assume data segments are relative to text segment.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 46879b7..4ed5542 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2017-06-28 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
+ * gcc.target/s390/nodatarel-1.c: New test.
+
2017-06-27 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/80164
diff --git a/gcc/testsuite/gcc.target/s390/nodatarel-1.c b/gcc/testsuite/gcc.target/s390/nodatarel-1.c
new file mode 100644
index 0000000..1d589a1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/nodatarel-1.c
@@ -0,0 +1,83 @@
+/* Test -mno-pic-data-is-text-relative option. No relative addressing
+ of elements in .data and .bss are allowed with that option. */
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-optimize-sibling-calls -fpic -mno-pic-data-is-text-relative -march=z10 -mtune=z9-109 -mzarch" } */
+
+static int a = 3;
+
+/* With -mno-pic-data-is-text-relative these must be addressed via
+ GOT. */
+
+int __attribute__((noinline,noclone))
+foo ()
+{
+ return a;
+}
+
+static int __attribute__((noinline,noclone))
+foostatic (void)
+{
+ return a;
+}
+
+/* Just to make a potentially modified. */
+
+void
+bar (int b)
+{
+ a = b;
+}
+
+/* { dg-final { scan-assembler-times "a@GOTENT" 3 } } */
+
+/* The exrl target is a label_ref which should not be affected at
+ all. */
+
+void
+mymemcpy (char *dst, char *src, long size)
+{
+ __builtin_memcpy (dst, src, size);
+}
+
+/* { dg-final { scan-assembler "exrl" } } */
+
+
+/* PLT slots can still be addressed relatively. */
+
+int
+callfoo ()
+{
+ return foo ();
+}
+
+/* { dg-final { scan-assembler-times "foo@PLT" 1 } } */
+
+
+/* GOT entries can still be addressed relatively. */
+
+void *
+fooptr ()
+{
+ return &foo;
+}
+
+/* { dg-final { scan-assembler-times "foo@GOTENT" 1 } } */
+
+
+/* A static function can be addressed relatively. */
+
+int
+callfoostatic ()
+{
+ return foostatic ();
+}
+
+void *
+foostaticptr ()
+{
+ return &foostatic;
+}
+
+
+/* { dg-final { scan-assembler-not "foostatic@" } } */