diff mbox series

S/390: Introduce jdd constraint

Message ID 20190207100915.38202-1-iii@linux.ibm.com
State New
Headers show
Series S/390: Introduce jdd constraint | expand

Commit Message

Ilya Leoshkevich Feb. 7, 2019, 10:09 a.m. UTC
Bootstrapped and regtested on s390x-redhat-linux.

Implementation of section anchors in S/390 back-end added in r266741
broke jump labels in S/390 Linux kernel [1].  Currently jump labels
pass global variable addresses to .quad directive in inline assembly
using "X" constraint.  In the past this used to produce regular symbol
references, however, after r266741 we sometimes get values like
(plus (reg) (const_int)), where (reg) points to a section anchor.
Strictly speaking, this is still correct, since "X" accepts anything.
Thus, now we need another way to support jump labels.

The existing "i" constraint cannot be used, since with -fPIC it must
not accept non-local symbols, however, jump labels do require that,
e.g. __tracepoint_xdp_exception from kernel proper might be referenced
from kernel modules.

The existing "ZL" constraint cannot be used for the same reason.

The existing "b" constraint cannot be used because of the way
expand_asm_stmt works.  It deduces whether the constraint allows
regs, subregs or mems, and processes asm operands differently based on
that.  "b" is supposed to accept values like (mem (symbol_ref)), and
there appears to be no way to explain to expand_asm_stmt that for "b"
mem's address must not be in a register.

This patch introduces the new machine-specific constraint named "jdd" -
"j" prefix is already used for constants, and "d" stands for "data".
It accepts anything that fits into the data section, whether or not
this might require a relocation, that is, anything that passes
CONSTANT_P check.

[1] https://lkml.org/lkml/2019/1/23/346

gcc/ChangeLog:

2019-02-06  Ilya Leoshkevich  <iii@linux.ibm.com>

	* config/s390/constraints.md (jdd): New constraint.

gcc/testsuite/ChangeLog:

2019-02-06  Ilya Leoshkevich  <iii@linux.ibm.com>

	* gcc.target/s390/jump-label.c: New test.
---
 gcc/config/s390/constraints.md             | 17 +++++++++++++++++
 gcc/testsuite/gcc.target/s390/jump-label.c | 19 +++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/s390/jump-label.c

Comments

Andreas Krebbel Feb. 8, 2019, 12:24 p.m. UTC | #1
On 07.02.19 11:09, Ilya Leoshkevich wrote:
> Bootstrapped and regtested on s390x-redhat-linux.
> 
> Implementation of section anchors in S/390 back-end added in r266741
> broke jump labels in S/390 Linux kernel [1].  Currently jump labels
> pass global variable addresses to .quad directive in inline assembly
> using "X" constraint.  In the past this used to produce regular symbol
> references, however, after r266741 we sometimes get values like
> (plus (reg) (const_int)), where (reg) points to a section anchor.
> Strictly speaking, this is still correct, since "X" accepts anything.
> Thus, now we need another way to support jump labels.
> 
> The existing "i" constraint cannot be used, since with -fPIC it must
> not accept non-local symbols, however, jump labels do require that,
> e.g. __tracepoint_xdp_exception from kernel proper might be referenced
> from kernel modules.
> 
> The existing "ZL" constraint cannot be used for the same reason.
> 
> The existing "b" constraint cannot be used because of the way
> expand_asm_stmt works.  It deduces whether the constraint allows
> regs, subregs or mems, and processes asm operands differently based on
> that.  "b" is supposed to accept values like (mem (symbol_ref)), and
> there appears to be no way to explain to expand_asm_stmt that for "b"
> mem's address must not be in a register.
> 
> This patch introduces the new machine-specific constraint named "jdd" -
> "j" prefix is already used for constants, and "d" stands for "data".
> It accepts anything that fits into the data section, whether or not
> this might require a relocation, that is, anything that passes
> CONSTANT_P check.
> 
> [1] https://lkml.org/lkml/2019/1/23/346
> 
> gcc/ChangeLog:
> 
> 2019-02-06  Ilya Leoshkevich  <iii@linux.ibm.com>
> 
> 	* config/s390/constraints.md (jdd): New constraint.
> 
> gcc/testsuite/ChangeLog:
> 
> 2019-02-06  Ilya Leoshkevich  <iii@linux.ibm.com>
> 
> 	* gcc.target/s390/jump-label.c: New test.

Ok. Thanks!

Andreas
diff mbox series

Patch

diff --git a/gcc/config/s390/constraints.md b/gcc/config/s390/constraints.md
index 688dd96e0e2..4055cbc7c68 100644
--- a/gcc/config/s390/constraints.md
+++ b/gcc/config/s390/constraints.md
@@ -37,6 +37,7 @@ 
 ;;         jKK: constant vector with all elements having the same value and
 ;;              matching K constraint
 ;;         jm6: An integer operand with the lowest order 6 bits all ones.
+;;         jdd: A constant operand that fits into the data section.
 ;;    t -- Access registers 36 and 37.
 ;;    v -- Vector registers v0-v31.
 ;;    C -- A signed 8-bit constant (-128..127)
@@ -567,3 +568,19 @@ 
 (define_constraint "ZL"
   "LARL operand when in 64-bit mode, otherwise nothing."
   (match_test "TARGET_64BIT && larl_operand (op, VOIDmode)"))
+
+;; This constraint must behave like "i", in particular, the matching values
+;; must never be placed into registers or memory by
+;; cfgexpand.c:expand_asm_stmt.  It could be straightforward to start its name
+;; with a letter from genpreds.c:const_int_constraints, however it would
+;; require using (match_code "const_int"), which is infeasible.  To achieve the
+;; same effect, that is, setting maybe_allows_reg and maybe_allows_mem to false
+;; in genpreds.c:add_constraint, we explicitly exclude reg, subreg and mem
+;; codes.
+(define_constraint "jdd"
+  "A constant operand that fits into the data section.
+   Usage of this constraint might produce a relocation."
+  (and (not (match_code "reg"))
+       (not (match_code "subreg"))
+       (not (match_code "mem"))
+       (match_test "CONSTANT_P (op)")))
diff --git a/gcc/testsuite/gcc.target/s390/jump-label.c b/gcc/testsuite/gcc.target/s390/jump-label.c
new file mode 100644
index 00000000000..3de73f6bb6c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/jump-label.c
@@ -0,0 +1,19 @@ 
+/* Test jdd constraint, which is used for linux kernel jump labels.  */
+
+/* { dg-do link } */
+/* { dg-options "-O2 -fPIC -shared" } */
+
+__attribute__ ((visibility ("default"))) extern int i;
+
+void f (void)
+{
+  asm goto (".pushsection foo\n"
+#if defined(__s390x__)
+            ".quad %0-.\n"
+#else
+            ".long %0-.\n"
+#endif
+            ".popsection\n"
+            : : "jdd" (&i) : : l);
+l:;
+}