From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1005) id 135043858409; Tue, 27 Feb 2024 06:56:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 135043858409 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1709017002; bh=GaxOdT+uNZ3NRd7ijKvd0lK2BDNoICxi9WlCXBIpfuo=; h=From:To:Subject:Date:From; b=HGbpxbfPcl95j0cXzAe/XXKJsafp6TVhOSEAB/Ik+HgW561d8syrCXyNimhG5yMEv WJpLmiD/Rp9l+NDD9IpfUHffBp1X1IRosR7CrNBupkyxPqzgV8T6gvitpWD2t3F8i4 VmA7bk5nPpjlak1mirpnjJKaYLu69prnfhYgHq2k= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Michael Meissner To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/meissner/heads/work160-vpair)] PR target/112886, Add %S to print_operand for vector pair support. X-Act-Checkin: gcc X-Git-Author: Michael Meissner X-Git-Refname: refs/users/meissner/heads/work160-vpair X-Git-Oldrev: 422fa4a7bae282c24ea0848ca5a85dced496f606 X-Git-Newrev: dba5190b31c619ffac3f6df7c439ded9a7c31e58 Message-Id: <20240227065642.135043858409@sourceware.org> Date: Tue, 27 Feb 2024 06:56:42 +0000 (GMT) List-Id: https://gcc.gnu.org/g:dba5190b31c619ffac3f6df7c439ded9a7c31e58 commit dba5190b31c619ffac3f6df7c439ded9a7c31e58 Author: Michael Meissner Date: Tue Feb 27 01:55:58 2024 -0500 PR target/112886, Add %S to print_operand for vector pair support. In looking at support for load vector pair and store vector pair for the PowerPC in GCC, I noticed that we were missing a print_operand output modifier if you are dealing with vector pairs to print the 2nd register in the vector pair. If the instruction inside of the asm used the Altivec encoding, then we could use the %L modifier: __vector_pair *p, *q, *r; // ... __asm__ ("vaddudm %0,%1,%2\n\tvaddudm %L0,%L1,%L2" : "=v" (*p) : "v" (*q), "v" (*r)); Likewise if we know the value to be in a tradiational FPR register, %L will work for instructions that use the VSX encoding: __vector_pair *p, *q, *r; // ... __asm__ ("xvadddp %x0,%x1,%x2\n\txvadddp %L0,%L1,%L2" : "=f" (*p) : "f" (*q), "f" (*r)); But if have a value that is in a traditional Altivec register, and the instruction uses the VSX encoding, %L will a value between 0 and 31, when it should give a value between 32 and 63. This patch adds %S that acts like %x, except that it adds 1 to the register number. This is version 2 of the patch. The only difference is I made the test case simpler to read. I have tested this on power10 and power9 little endian systems and on a power9 big endian system. There were no regressions in the patch. Can I apply it to the trunk? It would be nice if I could apply it to the open branches. Can I backport it after a burn-in period? 2024-02-27 Michael Meissner gcc/ PR target/112886 * config/rs6000/rs6000.cc (print_operand): Add %S output modifier. * doc/md.texi (Modifiers): Mention %S can be used like %x. gcc/testsuite/ PR target/112886 * /gcc.target/powerpc/pr112886.c: New test. Diff: --- gcc/config/rs6000/rs6000.cc | 10 +++++++--- gcc/doc/md.texi | 5 +++-- gcc/testsuite/gcc.target/powerpc/pr112886.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 127e4f454e3..a600169a4c5 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -14468,13 +14468,17 @@ print_operand (FILE *file, rtx x, int code) print_operand (file, x, 0); return; + case 'S': case 'x': - /* X is a FPR or Altivec register used in a VSX context. */ + /* X is a FPR or Altivec register used in a VSX context. %x prints + the VSX register number, %S prints the 2nd register number for + vector pair, decimal 128-bit floating and IBM 128-bit binary floating + values. */ if (!REG_P (x) || !VSX_REGNO_P (REGNO (x))) - output_operand_lossage ("invalid %%x value"); + output_operand_lossage ("invalid %%%c value", (code == 'S' ? 'S' : 'x')); else { - int reg = REGNO (x); + int reg = REGNO (x) + (code == 'S' ? 1 : 0); int vsx_reg = (FP_REGNO_P (reg) ? reg - 32 : reg - FIRST_ALTIVEC_REGNO + 32); diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 5730bda80dc..7b7e6507754 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -3386,8 +3386,9 @@ A VSX register (VSR), @code{vs0}@dots{}@code{vs63}. This is either an FPR (@code{vs0}@dots{}@code{vs31} are @code{f0}@dots{}@code{f31}) or a VR (@code{vs32}@dots{}@code{vs63} are @code{v0}@dots{}@code{v31}). -When using @code{wa}, you should use the @code{%x} output modifier, so that -the correct register number is printed. For example: +When using @code{wa}, you should use either the @code{%x} or @code{%S} +output modifier, so that the correct register number is printed. For +example: @smallexample asm ("xvadddp %x0,%x1,%x2" diff --git a/gcc/testsuite/gcc.target/powerpc/pr112886.c b/gcc/testsuite/gcc.target/powerpc/pr112886.c new file mode 100644 index 00000000000..4e59dcda6ea --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr112886.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target power10_ok } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */ + +/* PR target/112886: Test that print_operand %S gives the correct register + number for VSX registers (i.e. if the register is an Altivec register, the + register number is 32..63 instead of 0..31. */ + +void +test (__vector_pair *ptr1, __vector_pair *ptr2, __vector_pair *ptr3) +{ + register __vector_pair p asm ("vs10"); + register __vector_pair q asm ("vs42"); + register __vector_pair r asm ("vs44"); + + q = *ptr2; + r = *ptr3; + + __asm__ ("xvadddp %x0,%x1,%x2\n\txvadddp %S0,%S1,%S2" + : "=wa" (p) + : "wa" (q), "wa" (r)); + + *ptr1 = p; +} + +/* { dg-final { scan-assembler-times {\mxvadddp 10,42,44\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvadddp 11,43,45\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mlxvpx?\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mstxvpx?\M} 1 } } */