Let me repeat my reply on binutils list here :) Hi Luis:
I like this approach in general, but I would like to discuss that on toolchain sig meeting to make sure we can reaching a consensus for that between LLVM and GNU community, also make it standardize before we moving forward. Are you interested in presenting that and creating a PR to https://github.com/riscv-non-isa/riscv-c-api-doc to start the discussion? also it would be nice if you can present that on toolchain sig meeting :) Luis Silva <[email protected]> 於 2026年5月25日週一 下午10:26寫道: > > This series adds support for the RISC-V APEX (ARC Processor EXtension) > custom instruction mechanism to GCC. APEX allows users to declare > custom instructions at the C source level using #pragma intrinsic and > have the compiler generate the appropriate assembly, including > .extInstruction directives for the assembler. > > This work was presented at the GNU Cauldron 2025. > - https://www.youtube.com/watch?v=jHfxkAN3Qtw > > Jeff Law also attended the presentation and is CC'd on this series. > > APEX is not a new ISA extension in the traditional sense -- it does not > add new -march bits or predefined builtins. Instead, it provides a > pragma-driven interface where users bind C function declarations to > custom instruction opcodes at compile time. The compiler then replaces > calls to those functions with custom instructions. > > source file: > int foo_func (int, int); > #pragma intrinsic (foo_func, "foo", 7, XD) > int > main (void) > { > return foo_func (1, 2); > } > > output: > main: > li a5,2 > li a0,1 > foo a0,a0,a5 # APEX insn. > ret > > Four instruction formats are supported: > - XD: register-register (up to 3 operands, 8-bit opcode) > - XS: short-immediate (two registers + 8-bit signed immediate, 6-bit opcode) > - XI: immediate (one register + immediate, 5-bit opcode) > - XC: accumulator (dest = src0, 5-bit opcode) > > When no format is explicitly specified, the compiler infers it from the > function signature and opcode range. Multiple formats can be specified > for a single intrinsic (except XI, which is exclusive); the compiler > selects the appropriate encoding at each call site. > > Since APEX intrinsics are registered dynamically via pragmas, their > metadata must be explicitly serialized to survive link-time optimization. > The implementation adds a dedicated LTO section (LTO_section_riscv_apex) > with read/write hooks guarded by TARGET_RISCV_APEX. I initially > considered a generic target hook for LTO section read/write, but since > this is currently RISC-V specific, that would impose interface > requirements on other architectures that do not need it. If other > targets develop similar needs in the future, a common hook can be > factored out at that point. > > The directive syntax and instruction formats in this RISCV-V APEX port > are intentionally aligned with existing proprietary compiler and > architecture to maintain compatibility across toolchains. > > The binutils-gdb patch series adding APEX assembler and disassembler > support has been submitted for review: > https://sourceware.org/pipermail/binutils/2026-May/149426.html > > The "[4/4] RISC-V: Add APEX LTO serialization for intrinsics" patch > depends on: > 1. The binutils APEX support above (for testing) > 2. The previously submitted patch: > "testsuite: Add dg-lto-error directive and ltrans assembly scanning" > https://gcc.gnu.org/pipermail/gcc-patches/2026-May/716427.html > which adds generic LTO test infrastructure used by the APEX LTO tests. > > The series is structured as follows: > > [1/4] RISC-V: Add APEX backend machine description and constraints > RTL patterns (define_insn/define_expand) for all APEX instruction > formats, mode iterators, constraints, and the .extInstruction > emission helper. > > [2/4] RISC-V: Add APEX middle-end builtin registration and expansion > Dynamic builtin table, format inference, opcode validation, > immediate range checks, and RTL expansion. > > [3/4] RISC-V: Add APEX #pragma intrinsic frontend > C pragma parser, mnemonic validation, function lookup, format > flag parsing, and user-facing documentation in extend.texi. > > [4/4] RISC-V: Add APEX LTO serialization for intrinsics > Custom LTO section serialization/deserialization with > cross-translation-unit conflict detection, plus LTO tests. > > Tested on riscv64-unknown-elf and riscv32-unknown-elf with no > regressions. > > Luis Silva (4): > RISC-V: Add APEX backend machine description and constraints > RISC-V: Add APEX middle-end builtin registration and expansion > RISC-V: Add APEX #pragma intrinsic frontend > RISC-V: Add APEX LTO serialization for intrinsics > > gcc/config.gcc | 1 + > gcc/config/riscv/arcv-apex.md | 367 +++++++++ > gcc/config/riscv/arcv-builtins.cc | 760 ++++++++++++++++++ > gcc/config/riscv/arcv.cc | 102 +++ > gcc/config/riscv/constraints.md | 34 + > gcc/config/riscv/iterators.md | 6 + > gcc/config/riscv/riscv-builtins.cc | 14 + > gcc/config/riscv/riscv-c.cc | 224 ++++++ > gcc/config/riscv/riscv-protos.h | 20 +- > gcc/config/riscv/riscv-vector-builtins.h | 8 +- > gcc/config/riscv/riscv.h | 42 + > gcc/config/riscv/riscv.md | 1 + > gcc/config/riscv/t-riscv | 16 + > gcc/doc/extend.texi | 85 ++ > gcc/fold-const.cc | 12 + > gcc/lto-section-in.cc | 1 + > gcc/lto-streamer-out.cc | 6 + > gcc/lto-streamer.h | 6 + > gcc/lto/lto-common.cc | 6 + > gcc/testsuite/g++.target/riscv/apex/apex.exp | 30 + > .../g++.target/riscv/apex/arcv-apex-test1.C | 22 + > .../g++.target/riscv/apex/arcv-apex-test2.C | 14 + > .../g++.target/riscv/apex/arcv-apex-test3.C | 21 + > .../g++.target/riscv/apex/arcv-apex-test4.C | 33 + > .../g++.target/riscv/apex/arcv-apex-test5.C | 16 + > gcc/testsuite/gcc.target/riscv/apex/apex.exp | 53 ++ > .../gcc.target/riscv/apex/arcv-apex-err1.c | 4 + > .../gcc.target/riscv/apex/arcv-apex-err10.c | 14 + > .../gcc.target/riscv/apex/arcv-apex-err11.c | 11 + > .../gcc.target/riscv/apex/arcv-apex-err12.c | 11 + > .../gcc.target/riscv/apex/arcv-apex-err13.c | 13 + > .../gcc.target/riscv/apex/arcv-apex-err14.c | 4 + > .../gcc.target/riscv/apex/arcv-apex-err15.c | 9 + > .../riscv/apex/arcv-apex-err16-32.c | 14 + > .../riscv/apex/arcv-apex-err16-64.c | 14 + > .../riscv/apex/arcv-apex-err17-32.c | 13 + > .../riscv/apex/arcv-apex-err17-64.c | 13 + > .../gcc.target/riscv/apex/arcv-apex-err18.c | 7 + > .../gcc.target/riscv/apex/arcv-apex-err19.c | 13 + > .../gcc.target/riscv/apex/arcv-apex-err2.c | 4 + > .../gcc.target/riscv/apex/arcv-apex-err20.c | 16 + > .../gcc.target/riscv/apex/arcv-apex-err3.c | 4 + > .../gcc.target/riscv/apex/arcv-apex-err4.c | 4 + > .../gcc.target/riscv/apex/arcv-apex-err5.c | 6 + > .../gcc.target/riscv/apex/arcv-apex-err6.c | 4 + > .../gcc.target/riscv/apex/arcv-apex-err7.c | 4 + > .../gcc.target/riscv/apex/arcv-apex-err8.c | 4 + > .../gcc.target/riscv/apex/arcv-apex-err9.c | 12 + > .../riscv/apex/arcv-apex-lto-err1_0.c | 16 + > .../riscv/apex/arcv-apex-lto-err1_1.c | 9 + > .../riscv/apex/arcv-apex-lto-err2_0.c | 17 + > .../riscv/apex/arcv-apex-lto-err2_1.c | 9 + > .../riscv/apex/arcv-apex-lto-err3_0.c | 17 + > .../riscv/apex/arcv-apex-lto-err3_1.c | 9 + > .../riscv/apex/arcv-apex-lto-err4_0.c | 19 + > .../riscv/apex/arcv-apex-lto-err4_1.c | 9 + > .../riscv/apex/arcv-apex-lto-test1_0.c | 49 ++ > .../riscv/apex/arcv-apex-lto-test1_1.c | 25 + > .../riscv/apex/arcv-apex-lto-test2_0.c | 36 + > .../riscv/apex/arcv-apex-lto-test2_1.c | 15 + > .../riscv/apex/arcv-apex-lto-test3_0.c | 49 ++ > .../riscv/apex/arcv-apex-lto-test3_1.c | 25 + > .../riscv/apex/arcv-apex-lto-test4_0.c | 25 + > .../riscv/apex/arcv-apex-lto-test4_1.c | 12 + > .../riscv/apex/arcv-apex-lto-test5_0.c | 52 ++ > .../riscv/apex/arcv-apex-lto-test5_1.c | 20 + > .../gcc.target/riscv/apex/arcv-apex-test1.c | 22 + > .../gcc.target/riscv/apex/arcv-apex-test10.c | 22 + > .../gcc.target/riscv/apex/arcv-apex-test11.c | 22 + > .../gcc.target/riscv/apex/arcv-apex-test12.c | 21 + > .../gcc.target/riscv/apex/arcv-apex-test13.c | 22 + > .../gcc.target/riscv/apex/arcv-apex-test14.c | 20 + > .../gcc.target/riscv/apex/arcv-apex-test15.c | 20 + > .../gcc.target/riscv/apex/arcv-apex-test16.c | 20 + > .../gcc.target/riscv/apex/arcv-apex-test2.c | 16 + > .../gcc.target/riscv/apex/arcv-apex-test3.c | 15 + > .../gcc.target/riscv/apex/arcv-apex-test4.c | 39 + > .../gcc.target/riscv/apex/arcv-apex-test5.c | 63 ++ > .../gcc.target/riscv/apex/arcv-apex-test6.c | 63 ++ > .../gcc.target/riscv/apex/arcv-apex-test7.c | 17 + > .../gcc.target/riscv/apex/arcv-apex-test8.c | 17 + > .../gcc.target/riscv/apex/arcv-apex-test9.c | 20 + > 82 files changed, 2923 insertions(+), 7 deletions(-) > create mode 100644 gcc/config/riscv/arcv-apex.md > create mode 100644 gcc/config/riscv/arcv-builtins.cc > create mode 100644 gcc/config/riscv/arcv.cc > create mode 100644 gcc/testsuite/g++.target/riscv/apex/apex.exp > create mode 100644 gcc/testsuite/g++.target/riscv/apex/arcv-apex-test1.C > create mode 100644 gcc/testsuite/g++.target/riscv/apex/arcv-apex-test2.C > create mode 100644 gcc/testsuite/g++.target/riscv/apex/arcv-apex-test3.C > create mode 100644 gcc/testsuite/g++.target/riscv/apex/arcv-apex-test4.C > create mode 100644 gcc/testsuite/g++.target/riscv/apex/arcv-apex-test5.C > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/apex.exp > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err1.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err10.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err11.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err12.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err13.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err14.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err15.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err16-32.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err16-64.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err17-32.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err17-64.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err18.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err19.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err2.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err20.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err3.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err4.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err5.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err6.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err7.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err8.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-err9.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-err1_0.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-err1_1.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-err2_0.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-err2_1.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-err3_0.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-err3_1.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-err4_0.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-err4_1.c > create mode 100644 > gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-test1_0.c > create mode 100644 > gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-test1_1.c > create mode 100644 > gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-test2_0.c > create mode 100644 > gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-test2_1.c > create mode 100644 > gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-test3_0.c > create mode 100644 > gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-test3_1.c > create mode 100644 > gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-test4_0.c > create mode 100644 > gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-test4_1.c > create mode 100644 > gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-test5_0.c > create mode 100644 > gcc/testsuite/gcc.target/riscv/apex/arcv-apex-lto-test5_1.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test1.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test10.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test11.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test12.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test13.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test14.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test15.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test16.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test2.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test3.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test4.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test5.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test6.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test7.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test8.c > create mode 100644 gcc/testsuite/gcc.target/riscv/apex/arcv-apex-test9.c > > -- > 2.34.0 >
