diff options
author | Kito Cheng <kito.cheng@sifive.com> | 2024-11-14 17:24:45 +0800 |
---|---|---|
committer | Kito Cheng <kito.cheng@sifive.com> | 2024-12-17 22:28:05 +0800 |
commit | 2a22db391d1819f6068aa43e63632b350a0b4bec (patch) | |
tree | e5bb9a662099bfe01ea9db8300dfcd5038fdb58a | |
parent | 192790e994c9e15949e694e0a52010001b291611 (diff) | |
download | gcc-2a22db391d1819f6068aa43e63632b350a0b4bec.zip gcc-2a22db391d1819f6068aa43e63632b350a0b4bec.tar.gz gcc-2a22db391d1819f6068aa43e63632b350a0b4bec.tar.bz2 |
RISC-V: Implment N modifier for printing the register number rather than the register name
The modifier `N`, to print the raw encoding of a register. This is used
when using `.insn <length>, <encoding>`, where the user wants to pass
a value to the instruction in a known register, but where the
instruction doesn't follow the existing instruction formats, so the
assembly parser is not expecting a register name, just a raw integer.
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_print_operand): Add N.
* doc/extend.texi: Document for N,
gcc/testsuite/ChangeLog:
* gcc.target/riscv/modifier-N-fpr.c: New.
* gcc.target/riscv/modifier-N-vr.c: New.
* gcc.target/riscv/modifier-N.c: New.
-rw-r--r-- | gcc/config/riscv/riscv.cc | 23 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/modifier-N-fpr.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/modifier-N-vr.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/modifier-N.c | 16 |
5 files changed, 74 insertions, 0 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index db2329c..ed75c65 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -6833,6 +6833,7 @@ riscv_asm_output_opcode (FILE *asm_out_file, const char *p) 'S' Print shift-index of single-bit mask OP. '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). Note please keep this list and the list in riscv.md in sync. */ @@ -7079,6 +7080,28 @@ riscv_print_operand (FILE *file, rtx op, int letter) output_addr_const (file, newop); break; } + case 'N': + { + if (!REG_P(op)) + { + output_operand_lossage ("modifier 'N' require register operand"); + break; + } + + unsigned regno = REGNO (op); + unsigned offset = 0; + if (IN_RANGE (regno, GP_REG_FIRST, GP_REG_LAST)) + offset = GP_REG_FIRST; + else if (IN_RANGE (regno, FP_REG_FIRST, FP_REG_LAST)) + offset = FP_REG_FIRST; + else if (IN_RANGE (regno, V_REG_FIRST, V_REG_LAST)) + offset = V_REG_FIRST; + else + output_operand_lossage ("invalid register number for 'N' modifie"); + + asm_fprintf (file, "%u", (regno - offset)); + break; + } default: switch (code) { diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index ebd9701..d991aa0 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -12594,6 +12594,7 @@ The list below describes the supported modifiers and their effects for RISC-V. @headitem Modifier @tab Description @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). @end multitable @anchor{shOperandmodifiers} diff --git a/gcc/testsuite/gcc.target/riscv/modifier-N-fpr.c b/gcc/testsuite/gcc.target/riscv/modifier-N-fpr.c new file mode 100644 index 0000000..42590e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/modifier-N-fpr.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64if -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +void foo() { +/* +** foo: +** ... +** fadd.s\s*ft0,\s*8,\s*9 +** ... +*/ + register float fs0 __asm__ ("fs0"); + register float fs1 __asm__ ("fs1"); + __asm__ volatile("fadd.s ft0, %N0, %N1" : : "f" (fs0), "f" (fs1) : "memory"); +} diff --git a/gcc/testsuite/gcc.target/riscv/modifier-N-vr.c b/gcc/testsuite/gcc.target/riscv/modifier-N-vr.c new file mode 100644 index 0000000..ea591b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/modifier-N-vr.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gv -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#pragma riscv intrinsic "vector" + +void foo() { +/* +** foo: +** ... +** vadd.vv\s*v0,\s*1,\s*2 +** ... +*/ + register vint32m1_t v1 __asm__ ("v1"); + register vint32m1_t v2 __asm__ ("v2"); + __asm__ volatile("vadd.vv v0, %N0, %N1" : : "vr" (v1), "vr" (v2) : "memory"); +} diff --git a/gcc/testsuite/gcc.target/riscv/modifier-N.c b/gcc/testsuite/gcc.target/riscv/modifier-N.c new file mode 100644 index 0000000..fef2816 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/modifier-N.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */ +/* { dg-final { check-function-bodies "**" "" } } */ + + +void foo() { +/* +** foo: +** ... +** addi\s*t0,\s*9,\s*4 +** ... +*/ + register int s1 __asm__ ("s1"); + register int tp __asm__ ("tp"); + __asm__ volatile("addi t0, %N0, %N1" : : "r" (s1), "r" (tp) : "memory"); +} |