+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.
/* 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)
/* 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. */
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);
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)
{
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.
}
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))))
/* Return insn sequence to load the GOT register. */
-static GTY(()) rtx got_symbol;
rtx_insn *
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);
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
#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. */
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.
+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
--- /dev/null
+/* 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@" } } */