https://gcc.gnu.org/g:f597a596cf8cb7f89b7d1e944ddd4baaccff9019

commit f597a596cf8cb7f89b7d1e944ddd4baaccff9019
Author: Jin Ma <ji...@linux.alibaba.com>
Date:   Sun May 4 08:44:27 2025 -0600

    [PATCH] RISC-V: Implment H modifier for printing the next register name
    
    For RV32 inline assembly, when handling 64-bit integer data, it is
    often necessary to process the lower and upper 32 bits separately.
    Unfortunately, we can only output the current register name
    (lower 32 bits) but not the next register name (upper 32 bits).
    
    To address this, the modifier 'H' has been added to allow users
    to handle the upper 32 bits of the data. While I believe the
    modifier 'N' (representing the next register name) might be more
    suitable for this functionality, 'N' is already in use.
    Therefore, 'H' (representing the high register) was chosen instead.
    
    Co-Authored-By: Dimitar Dimitrov <dimi...@dinux.eu>
    
    gcc/ChangeLog:
    
            * config/riscv/riscv.cc (riscv_print_operand): Add H.
            * doc/extend.texi: Document for H.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/modifier-H-error-1.c: New test.
            * gcc.target/riscv/modifier-H-error-2.c: New test.
            * gcc.target/riscv/modifier-H.c: New test.
    
    (cherry picked from commit 89e58171bae30eacf5e8a281eb4758b2712aeed2)

Diff:
---
 gcc/config/riscv/riscv.cc                          | 22 ++++++++++++++++++++++
 gcc/doc/extend.texi                                |  1 +
 .../gcc.target/riscv/modifier-H-error-1.c          | 13 +++++++++++++
 .../gcc.target/riscv/modifier-H-error-2.c          | 11 +++++++++++
 gcc/testsuite/gcc.target/riscv/modifier-H.c        | 22 ++++++++++++++++++++++
 5 files changed, 69 insertions(+)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 064c12c49f3a..a0657323f65f 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -6879,6 +6879,7 @@ riscv_asm_output_opcode (FILE *asm_out_file, const char 
*p)
    'T' Print shift-index of inverted single-bit mask OP.
    '~' Print w if TARGET_64BIT is true; otherwise not print anything.
    'N'  Print register encoding as integer (0-31).
+   'H'  Print the name of the next register for integer.
 
    Note please keep this list and the list in riscv.md in sync.  */
 
@@ -7174,6 +7175,27 @@ riscv_print_operand (FILE *file, rtx op, int letter)
        asm_fprintf (file, "%u", (regno - offset));
        break;
       }
+    case 'H':
+      {
+       if (!REG_P (op))
+         {
+           output_operand_lossage ("modifier 'H' require register operand");
+           break;
+         }
+       if (REGNO (op) > 31)
+         {
+           output_operand_lossage ("modifier 'H' is for integer registers 
only");
+           break;
+         }
+       if (REGNO (op) == 31)
+         {
+           output_operand_lossage ("modifier 'H' cannot be applied to R31");
+           break;
+         }
+
+       fputs (reg_names[REGNO (op) + 1], file);
+       break;
+      }
     default:
       switch (code)
        {
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 0978c4c41b25..212d24875584 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -12585,6 +12585,7 @@ The list below describes the supported modifiers and 
their effects for RISC-V.
 @item @code{z} @tab Print ''@code{zero}'' instead of 0 if the operand is an 
immediate with a value of zero.
 @item @code{i} @tab Print the character ''@code{i}'' if the operand is an 
immediate.
 @item @code{N} @tab Print the register encoding as integer (0 - 31).
+@item @code{H} @tab Print the name of the next register for integer.
 @end multitable
 
 @anchor{shOperandmodifiers}
diff --git a/gcc/testsuite/gcc.target/riscv/modifier-H-error-1.c 
b/gcc/testsuite/gcc.target/riscv/modifier-H-error-1.c
new file mode 100644
index 000000000000..43ecff6498e5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/modifier-H-error-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -O0" } */
+
+float foo ()
+{
+  float ret;
+  asm ("fld\t%H0,(a0)\n\t":"=f"(ret));
+
+  return ret;
+}
+
+/* { dg-error "modifier 'H' is for integer registers only" "" { target { 
"riscv*-*-*" } } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/modifier-H-error-2.c 
b/gcc/testsuite/gcc.target/riscv/modifier-H-error-2.c
new file mode 100644
index 000000000000..db478b6ddf61
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/modifier-H-error-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -O0 " } */
+
+void foo ()
+{
+  register int x31 __asm__ ("x31");
+  asm ("li\t%H0,1\n\t":"=r"(x31));
+}
+
+/* { dg-error "modifier 'H' cannot be applied to R31" "" { target { 
"riscv*-*-*" } } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/modifier-H.c 
b/gcc/testsuite/gcc.target/riscv/modifier-H.c
new file mode 100644
index 000000000000..3571ea966f04
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/modifier-H.c
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -O0" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+typedef long long __int64;
+
+__int64 foo ()
+{
+/*
+** foo:
+**   ...
+**   li\t[atx][0-9]+,1
+**   li\t[atx][0-9]+,1
+**   ...
+*/
+  __int64 ret;
+  asm ("li\t%0,1\n\tli\t%H0,1\n\t":"=r"(ret));
+
+  return ret;
+}
+

Reply via email to