On Fri, Apr 25, 2025 at 01:25:50PM +0800, Jin Ma wrote:
> 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.
> 
> Does anyone have any comments on this?
> 
> 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.c: New test.
> ---
>  gcc/config/riscv/riscv.cc                   | 12 +++++++++++
>  gcc/doc/extend.texi                         |  1 +
>  gcc/testsuite/gcc.target/riscv/modifier-H.c | 22 +++++++++++++++++++++
>  3 files changed, 35 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/modifier-H.c
> 
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index bad59e248d0..4ef96532f35 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 high register for OP, which is the next 
> register.
>  
>     Note please keep this list and the list in riscv.md in sync.  */
>  
> @@ -7174,6 +7175,17 @@ 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;
> +       }

Given the intended usage, does it make sense to limit this modifier only
to regular integer registers? Example:

  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;
    }

Is it an error to apply H modifier to R0?

If not, would you consider rejecting the last HW register:
  if (REGNO (op) >= FIRST_PSEUDO_REGISTER - 1 )
    {
      output_operand_lossage ("modifier 'H' cannot be applied to last HW 
register");
      break;
    }

Regards,
Dimitar

Reply via email to