Message ID | 20190207100915.38202-1-iii@linux.ibm.com |
---|---|
State | New |
Headers | show |
Series | S/390: Introduce jdd constraint | expand |
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 --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:; +}