https://gcc.gnu.org/g:86a1acfd86f881c32e0ae57036df65edd7d1d441
commit r15-7044-g86a1acfd86f881c32e0ae57036df65edd7d1d441 Author: Stefan Schulze Frielinghaus <stefa...@gcc.gnu.org> Date: Mon Jan 20 10:01:09 2025 +0100 s390: arch15: Load indexed address Add instructions lxa and llxa. gcc/ChangeLog: * config/s390/s390.md (*lxa<LXAMODE>_index): Add. (*lxa<LXAMODE>_displacement_index): Add. (*lxa<LXAMODE>_index_base): Add. (*lxa<LXAMODE>_displacement_index_base): Add. (*lxab_displacement_index_base): Add. (*llxa<LXAMODE>_displacement_index): Add. (*llxa<LXAMODE>_index_base): Add. (*llxa<LXAMODE>_displacement_index_base): Add. (*llxab_displacement_index_base): Add. gcc/testsuite/ChangeLog: * gcc.target/s390/llxa-1.c: New test. * gcc.target/s390/llxa-2.c: New test. * gcc.target/s390/llxa-3.c: New test. * gcc.target/s390/lxa-1.c: New test. * gcc.target/s390/lxa-2.c: New test. * gcc.target/s390/lxa-3.c: New test. * gcc.target/s390/lxa-4.c: New test. Diff: --- gcc/config/s390/s390.md | 105 +++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/s390/llxa-1.c | 34 +++++++++++ gcc/testsuite/gcc.target/s390/llxa-2.c | 34 +++++++++++ gcc/testsuite/gcc.target/s390/llxa-3.c | 41 +++++++++++++ gcc/testsuite/gcc.target/s390/lxa-1.c | 34 +++++++++++ gcc/testsuite/gcc.target/s390/lxa-2.c | 34 +++++++++++ gcc/testsuite/gcc.target/s390/lxa-3.c | 34 +++++++++++ gcc/testsuite/gcc.target/s390/lxa-4.c | 42 +++++++++++++ 8 files changed, 358 insertions(+) diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 6a660f108b79..6fed6bf42543 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -1963,6 +1963,111 @@ *,*,yes") ]) +; LOAD INDEXED ADDRESS +; lxab, lxah, lxaf, lxag, lxaq + +(define_int_iterator LXAMODEITER [1 2 3 4]) +(define_int_attr lxamode [(1 "h") (2 "f") (3 "g") (4 "q")]) + +; see testsuite/gcc.target/s390/lxa-1.c +(define_insn "*lxa<lxamode>_index" + [(set (match_operand:DI 0 "register_operand" "=d") + (ashift:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "a")) + (const_int LXAMODEITER)))] + "TARGET_ARCH15 && TARGET_64BIT" + "lxa<lxamode>\t%0,0(%1,0)" + [(set_attr "op_type" "RXY")]) + +; see testsuite/gcc.target/s390/lxa-2.c +(define_insn "*lxa<lxamode>_displacement_index" + [(set (match_operand:DI 0 "register_operand" "=d") + (ashift:DI (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "a") + (match_operand:SI 2 "const_int_operand"))) + (const_int LXAMODEITER)))] + "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF" + "lxa<lxamode>\t%0,%2(%1,0)" + [(set_attr "op_type" "RXY")]) + +; see testsuite/gcc.target/s390/lxa-3.c +(define_insn "*lxa<lxamode>_index_base" + [(set (match_operand:DI 0 "register_operand" "=d") + (plus:DI (ashift:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "a")) + (const_int LXAMODEITER)) + (match_operand:DI 2 "register_operand" "a")))] + "TARGET_ARCH15 && TARGET_64BIT" + "lxa<lxamode>\t%0,0(%1,%2)" + [(set_attr "op_type" "RXY")]) + +; see testsuite/gcc.target/s390/lxa-4.c +(define_insn "*lxa<lxamode>_displacement_index_base" + [(set (match_operand:DI 0 "register_operand" "=d") + (plus:DI (ashift:DI (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "a") + (match_operand:SI 2 "const_int_operand"))) + (const_int LXAMODEITER)) + (match_operand:DI 3 "register_operand" "a")))] + "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF" + "lxa<lxamode>\t%0,%2(%1,%3)" + [(set_attr "op_type" "RXY")]) + +(define_insn "*lxab_displacement_index_base" + [(set (match_operand:DI 0 "register_operand" "=d") + (plus:DI (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "a") + (match_operand:SI 2 "const_int_operand"))) + (match_operand:DI 3 "register_operand" "a")))] + "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF" + "lxab\t%0,%2(%1,%3)" + [(set_attr "op_type" "RXY")]) + +; LOAD LOGICAL INDEXED ADDRESS +; llxab, llxah, llxaf, llxag, llxaq + +(define_int_attr LLXAMASK [(1 "8589934590") (2 "17179869180") (3 "34359738360") (4 "68719476720")]) + +; see testsuite/gcc.target/s390/llxa-1.c +(define_insn "*llxa<lxamode>_displacement_index" + [(set (match_operand:DI 0 "register_operand" "=d") + (and:DI (ashift:DI (subreg:DI (plus:SI (match_operand:SI 1 "register_operand" "a") + (match_operand:SI 2 "const_int_operand")) + 0) + (const_int LXAMODEITER)) + (const_int <LLXAMASK>)))] + "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF" + "llxa<lxamode>\t%0,%2(%1,0)" + [(set_attr "op_type" "RXY")]) + +; see testsuite/gcc.target/s390/llxa-2.c +(define_insn "*llxa<lxamode>_index_base" + [(set (match_operand:DI 0 "register_operand" "=d") + (plus:DI (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "a") + (const_int LXAMODEITER)) + (const_int <LLXAMASK>)) + (match_operand:DI 2 "register_operand" "a")))] + "TARGET_ARCH15 && TARGET_64BIT" + "llxa<lxamode>\t%0,0(%1,%2)" + [(set_attr "op_type" "RXY")]) + +; see testsuite/gcc.target/s390/llxa-3.c +(define_insn "*llxa<lxamode>_displacement_index_base" + [(set (match_operand:DI 0 "register_operand" "=d") + (plus:DI (and:DI (ashift:DI (subreg:DI (plus:SI (match_operand:SI 1 "register_operand" "a") + (match_operand:SI 2 "const_int_operand")) + 0) + (const_int LXAMODEITER)) + (const_int <LLXAMASK>)) + (match_operand:DI 3 "register_operand" "a")))] + "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF" + "llxa<lxamode>\t%0,%2(%1,%3)" + [(set_attr "op_type" "RXY")]) + +(define_insn "*llxab_displacement_index_base" + [(set (match_operand:DI 0 "register_operand" "=d") + (plus:DI (zero_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "a") + (match_operand:SI 2 "const_int_operand"))) + (match_operand:DI 3 "register_operand" "a")))] + "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF" + "llxab\t%0,%2(%1,%3)" + [(set_attr "op_type" "RXY")]) + ; Splitters for loading TLS pointer from UNSPEC_GET_TP. ; UNSPEC_GET_TP is used instead of %a0:P, since the latter is a hard register, ; and those are not handled by Partial Redundancy Elimination (gcse.cc), which diff --git a/gcc/testsuite/gcc.target/s390/llxa-1.c b/gcc/testsuite/gcc.target/s390/llxa-1.c new file mode 100644 index 000000000000..e01ae100ba84 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/llxa-1.c @@ -0,0 +1,34 @@ +/* { dg-do compile { target { lp64 } } } */ +/* { dg-options "-O1 -march=arch15" } */ +/* { dg-final { scan-assembler {\tllxah\t%r[0-9]+,42\(%r[0-9]+,0\)} } } */ +/* { dg-final { scan-assembler {\tllxaf\t%r[0-9]+,42\(%r[0-9]+,0\)} } } */ +/* { dg-final { scan-assembler {\tllxag\t%r[0-9]+,42\(%r[0-9]+,0\)} } } */ +/* { dg-final { scan-assembler {\tllxaq\t%r[0-9]+,42\(%r[0-9]+,0\)} } } */ + +unsigned long +llxah (long j) +{ + unsigned long i = (unsigned int)j + 42; + return i << 1; +} + +unsigned long +llxaf (long j) +{ + unsigned long i = (unsigned int)j + 42; + return i << 2; +} + +unsigned long +llxag (long j) +{ + unsigned long i = (unsigned int)j + 42; + return i << 3; +} + +unsigned long +llxaq (long j) +{ + unsigned long i = (unsigned int)j + 42; + return i << 4; +} diff --git a/gcc/testsuite/gcc.target/s390/llxa-2.c b/gcc/testsuite/gcc.target/s390/llxa-2.c new file mode 100644 index 000000000000..59f760b718e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/llxa-2.c @@ -0,0 +1,34 @@ +/* { dg-do compile { target { lp64 } } } */ +/* { dg-options "-O1 -march=arch15" } */ +/* { dg-final { scan-assembler {\tllxah\t%r[0-9]+,0\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tllxaf\t%r[0-9]+,0\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tllxag\t%r[0-9]+,0\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tllxaq\t%r[0-9]+,0\(%r[0-9]+,%r[0-9]+\)} } } */ + +short * +llxah (short *a, unsigned long j) +{ + unsigned int i = (unsigned int)j; + return &a[i]; +} + +int * +llxaf (int *a, unsigned long j) +{ + unsigned int i = (unsigned int)j; + return &a[i]; +} + +long long * +llxag (long long *a, unsigned long j) +{ + unsigned int i = (unsigned int)j; + return &a[i]; +} + +__int128 * +llxaq (__int128 *a, unsigned long j) +{ + unsigned int i = (unsigned int)j; + return &a[i]; +} diff --git a/gcc/testsuite/gcc.target/s390/llxa-3.c b/gcc/testsuite/gcc.target/s390/llxa-3.c new file mode 100644 index 000000000000..bebee29608ad --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/llxa-3.c @@ -0,0 +1,41 @@ +/* { dg-do compile { target { lp64 } } } */ +/* { dg-options "-O1 -march=arch15" } */ +/* { dg-final { scan-assembler {\tllxah\t%r[0-9]+,42\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tllxaf\t%r[0-9]+,42\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tllxag\t%r[0-9]+,42\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tllxaq\t%r[0-9]+,42\(%r[0-9]+,%r[0-9]+\)} } } */ + +char * +llxab (char *a, unsigned long j) +{ + unsigned int i = (unsigned int)j + 42; + return &a[i]; +} + +short * +llxah (short *a, unsigned long j) +{ + unsigned int i = (unsigned int)j + 42; + return &a[i]; +} + +int * +llxaf (int *a, unsigned long j) +{ + unsigned int i = (unsigned int)j + 42; + return &a[i]; +} + +long long * +llxag (long long *a, unsigned long j) +{ + unsigned int i = (unsigned int)j + 42; + return &a[i]; +} + +__int128 * +llxaq (__int128 *a, unsigned long j) +{ + unsigned int i = (unsigned int)j + 42; + return &a[i]; +} diff --git a/gcc/testsuite/gcc.target/s390/lxa-1.c b/gcc/testsuite/gcc.target/s390/lxa-1.c new file mode 100644 index 000000000000..ed97b23ea7f6 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/lxa-1.c @@ -0,0 +1,34 @@ +/* { dg-do compile { target { lp64 } } } */ +/* { dg-options "-O1 -march=arch15" } */ +/* { dg-final { scan-assembler {\tlxah\t%r[0-9]+,0\(%r[0-9]+,0\)} } } */ +/* { dg-final { scan-assembler {\tlxaf\t%r[0-9]+,0\(%r[0-9]+,0\)} } } */ +/* { dg-final { scan-assembler {\tlxag\t%r[0-9]+,0\(%r[0-9]+,0\)} } } */ +/* { dg-final { scan-assembler {\tlxaq\t%r[0-9]+,0\(%r[0-9]+,0\)} } } */ + +long +lxah (long j) +{ + long i = (int)j; + return i << 1; +} + +long +lxaf (long j) +{ + long i = (int)j; + return i << 2; +} + +long +lxag (long j) +{ + long i = (int)j; + return i << 3; +} + +long +lxaq (long j) +{ + long i = (int)j; + return i << 4; +} diff --git a/gcc/testsuite/gcc.target/s390/lxa-2.c b/gcc/testsuite/gcc.target/s390/lxa-2.c new file mode 100644 index 000000000000..075e5996fb05 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/lxa-2.c @@ -0,0 +1,34 @@ +/* { dg-do compile { target { lp64 } } } */ +/* { dg-options "-O1 -march=arch15" } */ +/* { dg-final { scan-assembler {\tlxah\t%r[0-9]+,42\(%r[0-9]+,0\)} } } */ +/* { dg-final { scan-assembler {\tlxaf\t%r[0-9]+,42\(%r[0-9]+,0\)} } } */ +/* { dg-final { scan-assembler {\tlxag\t%r[0-9]+,42\(%r[0-9]+,0\)} } } */ +/* { dg-final { scan-assembler {\tlxaq\t%r[0-9]+,42\(%r[0-9]+,0\)} } } */ + +long +lxah (long j) +{ + long i = (int)j + 42; + return i << 1; +} + +long +lxaf (long j) +{ + long i = (int)j + 42; + return i << 2; +} + +long +lxag (long j) +{ + long i = (int)j + 42; + return i << 3; +} + +long +lxaq (long j) +{ + long i = (int)j + 42; + return i << 4; +} diff --git a/gcc/testsuite/gcc.target/s390/lxa-3.c b/gcc/testsuite/gcc.target/s390/lxa-3.c new file mode 100644 index 000000000000..7ff44e4efbbe --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/lxa-3.c @@ -0,0 +1,34 @@ +/* { dg-do compile { target { lp64 } } } */ +/* { dg-options "-O1 -march=arch15" } */ +/* { dg-final { scan-assembler {\tlxah\t%r[0-9]+,0\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tlxaf\t%r[0-9]+,0\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tlxag\t%r[0-9]+,0\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tlxaq\t%r[0-9]+,0\(%r[0-9]+,%r[0-9]+\)} } } */ + +short * +lxah (short *a, long j) +{ + int i = (int)j; + return &a[i]; +} + +int * +lxaf (int *a, long j) +{ + int i = (int)j; + return &a[i]; +} + +long long * +lxag (long long *a, long j) +{ + int i = (int)j; + return &a[i]; +} + +__int128 * +lxaq (__int128 *a, long j) +{ + int i = (int)j; + return &a[i]; +} diff --git a/gcc/testsuite/gcc.target/s390/lxa-4.c b/gcc/testsuite/gcc.target/s390/lxa-4.c new file mode 100644 index 000000000000..879a15a270c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/lxa-4.c @@ -0,0 +1,42 @@ +/* { dg-do compile { target { lp64 } } } */ +/* { dg-options "-O1 -march=arch15" } */ +/* { dg-final { scan-assembler {\tlxab\t%r[0-9]+,42\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tlxah\t%r[0-9]+,42\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tlxaf\t%r[0-9]+,42\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tlxag\t%r[0-9]+,42\(%r[0-9]+,%r[0-9]+\)} } } */ +/* { dg-final { scan-assembler {\tlxaq\t%r[0-9]+,42\(%r[0-9]+,%r[0-9]+\)} } } */ + +char * +lxab (char *a, long j) +{ + int i = (int)j + 42; + return &a[i]; +} + +short * +lxah (short *a, long j) +{ + int i = (int)j + 42; + return &a[i]; +} + +int * +lxaf (int *a, long j) +{ + int i = (int)j + 42; + return &a[i]; +} + +long long * +lxag (long long *a, long j) +{ + int i = (int)j + 42; + return &a[i]; +} + +__int128 * +lxaq (__int128 *a, long j) +{ + int i = (int)j + 42; + return &a[i]; +}