[PATCH v3] riscv: asm: use .insn for making custom instructions
Nathan Chancellor
nathan at kernel.org
Thu Oct 30 20:10:09 PDT 2025
Hey Ben,
On Fri, Oct 24, 2025 at 06:16:40PM +0100, Ben Dooks wrote:
> The assembler has .insn for building custom instructions
> now, so change the .4byte to .insn. This ensures the output
> is marked as an instruction and not as data which may
> confuse both debuggers and anything else that relies on
> this sort of marking.
>
> Add an ASM_INSN_I() wrapper in asm.h to allow the selecting
> of how this is output so older assemblers are still good.
>
> Reviewed-by: Andrew Jones <ajones at ventanamicro.com>
> Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
> ---
> v2:
> - fixed #ifndef v #ifdef
> - added custom MIPS instructions too
> - new patch description
> v3:
> - fixed typo missed in compile test of NOP4
> - fixed incorrect MIPS changes
> - re-wored slightly to shorten sentences and remove typos
> ---
> arch/riscv/include/asm/asm.h | 6 ++++++
> arch/riscv/include/asm/insn-def.h | 8 ++++----
> arch/riscv/include/asm/vendor_extensions/mips.h | 6 +++---
> 3 files changed, 13 insertions(+), 7 deletions(-)
>
> diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
> index 8bd2a11382a3..2d97436999ca 100644
> --- a/arch/riscv/include/asm/asm.h
> +++ b/arch/riscv/include/asm/asm.h
> @@ -12,6 +12,12 @@
> #define __ASM_STR(x) #x
> #endif
>
> +#ifdef CONFIG_AS_HAS_INSN
The current AS_HAS_INSN check in Kconfig is not sufficient for this
usage. With LLVM prior to [1] (i.e., older than 19) or GNU binutils
prior to [2] (i.e., older than 2.38), the build breaks:
In file included from <built-in>:4:
In file included from lib/vdso/gettimeofday.c:6:
In file included from include/vdso/datapage.h:21:
In file included from include/vdso/processor.h:10:
arch/riscv/include/asm/vdso/processor.h:23:2: error: expected instruction format
23 | ALT_RISCV_PAUSE();
| ^
arch/riscv/include/asm/errata_list.h:47:3: note: expanded from macro 'ALT_RISCV_PAUSE'
47 | RISCV_PAUSE, /* Original RISC‑V pause insn */ \
| ^
arch/riscv/include/asm/insn-def.h:259:21: note: expanded from macro 'RISCV_PAUSE'
259 | #define RISCV_PAUSE ASM_INSN_I("0x100000f")
| ^
arch/riscv/include/asm/asm.h:16:26: note: expanded from macro 'ASM_INSN_I'
16 | #define ASM_INSN_I(__x) ".insn " __x
| ^
<inline asm>:5:7: note: instantiated into assembly here
5 | .insn 0x100000f
| ^
arch/riscv/include/asm/vdso/processor.h: Assembler messages:
arch/riscv/include/asm/vdso/processor.h:27: Error: unrecognized opcode `0x100000f'
arch/riscv/include/asm/vdso/processor.h:27: Error: unrecognized opcode `0x100000f'
arch/riscv/include/asm/vdso/processor.h:27: Error: unrecognized opcode `0x100000f'
arch/riscv/include/asm/vdso/processor.h:27: Error: unrecognized opcode `0x100000f'
make[4]: *** [scripts/Makefile.build:287: arch/riscv/kernel/vdso/vgettimeofday.o] Error 1
Maybe this wants a new symbol like CONFIG_AS_HAS_INSN_EXT that checks
for this support?
[1]: https://github.com/llvm/llvm-project/commit/2a086dce691e3cc34a2fc27f4fb255bb2cbbfac9
[2]: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=a262b82fdbf4cda3b0648b1adc32245ca3f78b7a
Cheers,
Nathan
> +#define ASM_INSN_I(__x) ".insn " __x
> +#else
> +#define ASM_INSN_I(__x) ".4byte " __x
> +#endif
> +
> #if __riscv_xlen == 64
> #define __REG_SEL(a, b) __ASM_STR(a)
> #elif __riscv_xlen == 32
> diff --git a/arch/riscv/include/asm/insn-def.h b/arch/riscv/include/asm/insn-def.h
> index c9cfcea52cbb..d29da6ccd3dd 100644
> --- a/arch/riscv/include/asm/insn-def.h
> +++ b/arch/riscv/include/asm/insn-def.h
> @@ -256,10 +256,10 @@
> INSN_S(OPCODE_OP_IMM, FUNC3(6), __RS2(3), \
> SIMM12((offset) & 0xfe0), RS1(base))
>
> -#define RISCV_PAUSE ".4byte 0x100000f"
> -#define ZAWRS_WRS_NTO ".4byte 0x00d00073"
> -#define ZAWRS_WRS_STO ".4byte 0x01d00073"
> -#define RISCV_NOP4 ".4byte 0x00000013"
> +#define RISCV_PAUSE ASM_INSN_I("0x100000f")
> +#define ZAWRS_WRS_NTO ASM_INSN_I("0x00d00073")
> +#define ZAWRS_WRS_STO ASM_INSN_I("0x01d00073")
> +#define RISCV_NOP4 ASM_INSN_I("0x00000013")
>
> #define RISCV_INSN_NOP4 _AC(0x00000013, U)
>
> diff --git a/arch/riscv/include/asm/vendor_extensions/mips.h b/arch/riscv/include/asm/vendor_extensions/mips.h
> index ea8ca747d691..ffeb12dc17a3 100644
> --- a/arch/riscv/include/asm/vendor_extensions/mips.h
> +++ b/arch/riscv/include/asm/vendor_extensions/mips.h
> @@ -30,8 +30,8 @@ extern struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_mips;
> * allowing any subsequent instructions to fetch.
> */
>
> -#define MIPS_PAUSE ".4byte 0x00501013\n\t"
> -#define MIPS_EHB ".4byte 0x00301013\n\t"
> -#define MIPS_IHB ".4byte 0x00101013\n\t"
> +#define MIPS_PAUSE ASM_INSN_I("0x00501013\n\t")
> +#define MIPS_EHB ASM_INSN_I("0x00301013\n\t")
> +#define MIPS_IHB ASM_INSN_I("0x00101013\n\t")
>
> #endif // _ASM_RISCV_VENDOR_EXTENSIONS_MIPS_H
> --
> 2.37.2.352.g3c44437643
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
More information about the linux-riscv
mailing list