[0/2] RISC-V: Add ARC-V APEX assembler and disassembler support

Message ID 20260525133052.1885254-1-luiss@synopsys.com
Headers
Series RISC-V: Add ARC-V APEX assembler and disassembler support |

Message

Luis Silva May 25, 2026, 1:30 p.m. UTC
  This series adds assembler and disassembler support for ARC-V APEX
(ARC Processor EXtension) custom instructions on RISC-V.

This work was presented at the GNU Cauldron 2025.
- https://www.youtube.com/watch?v=jHfxkAN3Qtw

Jeff Law and Kito Cheng attended the presentation and are CC'd on this
series.

APEX allows users to dynamically define instructions that encode into the
Custom-0 major opcode space (opcode 0x0b).  Rather than extending the
static opcode table, instructions are declared at assembly time via a new
.extInstruction directive:

  .extInstruction <name>, <sub_opcode>, <format>[, <attributes>]

Four instruction formats are supported:

  - XD: 3-register, 8-bit sub-opcode (up to 256 instructions)
  - XS: 2-register + 8-bit signed immediate, 6-bit sub-opcode (up to 64)
  - XI: 1-register + 12-bit signed immediate, 5-bit sub-opcode (up to 32)
  - XC: rd==rs1 variant of XI, 5-bit sub-opcode (up to 32)

XS and XC can be paired so the assembler automatically selects the
encoding based on operand constraints.

To preserve instruction definitions through linking, the assembler emits
a metadata record for each .extInstruction into a COMDAT ELF section
named .riscvapex.<fmt>.<major>.<sub_opcode>.  The disassembler reads
these sections at startup, reconstructs the opcode entries, and falls
back to them when the standard opcode table produces no match.

The directive syntax, instruction formats, and metadata representation
in this RISCV-V APEX port are intentionally aligned with existing
proprietary compiler and architecture to maintain compatibility across
toolchains.

Patch 1 adds the assembler: .extInstruction parsing, validation,
encoding, and metadata emission, along with documentation and tests
(4 positive + 10 negative cases).

Patch 2 adds the disassembler: metadata deserialization, dynamic opcode
reconstruction, and APEX-specific decode path, plus 2 linker tests
verifying metadata sections survive linking.

Tested with the gas, ld and gdb testsuites for riscv-elf targets.

Luis Silva (2):
  RISC-V: Add ARC-V APEX assembler support
  RISC-V: Add ARC-V APEX disassembler support

 gas/config/tc-riscv.c                         | 631 ++++++++++++++++++
 gas/doc/c-riscv.texi                          |  53 ++
 gas/testsuite/gas/riscv/x-arcv-apex-01.d      |  18 +
 gas/testsuite/gas/riscv/x-arcv-apex-01.s      |  19 +
 gas/testsuite/gas/riscv/x-arcv-apex-02.d      |  13 +
 gas/testsuite/gas/riscv/x-arcv-apex-02.s      |   6 +
 gas/testsuite/gas/riscv/x-arcv-apex-03.d      |  46 ++
 gas/testsuite/gas/riscv/x-arcv-apex-04.d      |  15 +
 gas/testsuite/gas/riscv/x-arcv-apex-04.s      |  10 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-01.d |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-01.l |   2 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-01.s |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-02.d |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-02.l |   5 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-02.s |   3 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-03.d |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-03.l |   9 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-03.s |  12 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-04.d |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-04.l |   3 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-04.s |   2 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-05.d |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-05.l |   3 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-05.s |   3 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-06.d |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-06.l |   7 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-06.s |   7 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-07.d |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-07.l |   9 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-07.s |   9 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-08.d |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-08.l |   5 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-08.s |   7 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-09.d |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-09.l |   3 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-09.s |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-10.d |   1 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-10.l |   3 +
 gas/testsuite/gas/riscv/x-arcv-apex-fail-10.s |   2 +
 include/opcode/riscv.h                        |  74 ++
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp    |  10 +
 ld/testsuite/ld-riscv-elf/x-arcv-apex-01-a.s  |   8 +
 ld/testsuite/ld-riscv-elf/x-arcv-apex-01-b.s  |  21 +
 ld/testsuite/ld-riscv-elf/x-arcv-apex-01-c.s  |  21 +
 ld/testsuite/ld-riscv-elf/x-arcv-apex-01.d    |  32 +
 ld/testsuite/ld-riscv-elf/x-arcv-apex-02.d    |  36 +
 opcodes/riscv-dis.c                           | 269 ++++++++
 opcodes/riscv-opc.c                           | 140 ++++
 48 files changed, 1528 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-01.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-01.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-02.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-02.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-03.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-04.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-04.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-01.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-01.l
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-01.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-02.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-02.l
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-02.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-03.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-03.l
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-03.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-04.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-04.l
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-04.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-05.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-05.l
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-05.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-06.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-06.l
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-06.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-07.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-07.l
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-07.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-08.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-08.l
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-08.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-09.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-09.l
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-09.s
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-10.d
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-10.l
 create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-10.s
 create mode 100644 ld/testsuite/ld-riscv-elf/x-arcv-apex-01-a.s
 create mode 100644 ld/testsuite/ld-riscv-elf/x-arcv-apex-01-b.s
 create mode 100644 ld/testsuite/ld-riscv-elf/x-arcv-apex-01-c.s
 create mode 100644 ld/testsuite/ld-riscv-elf/x-arcv-apex-01.d
 create mode 100644 ld/testsuite/ld-riscv-elf/x-arcv-apex-02.d
  

Comments

Kito Cheng May 25, 2026, 2:17 p.m. UTC | #1
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.

Do you have interested to present that and create 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 <Luis.Silva1@synopsys.com> 於 2026年5月25日週一 下午9:31寫道:
>
> This series adds assembler and disassembler support for ARC-V APEX
> (ARC Processor EXtension) custom instructions on RISC-V.
>
> This work was presented at the GNU Cauldron 2025.
> - https://www.youtube.com/watch?v=jHfxkAN3Qtw
>
> Jeff Law and Kito Cheng attended the presentation and are CC'd on this
> series.
>
> APEX allows users to dynamically define instructions that encode into the
> Custom-0 major opcode space (opcode 0x0b).  Rather than extending the
> static opcode table, instructions are declared at assembly time via a new
> .extInstruction directive:
>
>   .extInstruction <name>, <sub_opcode>, <format>[, <attributes>]
>
> Four instruction formats are supported:
>
>   - XD: 3-register, 8-bit sub-opcode (up to 256 instructions)
>   - XS: 2-register + 8-bit signed immediate, 6-bit sub-opcode (up to 64)
>   - XI: 1-register + 12-bit signed immediate, 5-bit sub-opcode (up to 32)
>   - XC: rd==rs1 variant of XI, 5-bit sub-opcode (up to 32)
>
> XS and XC can be paired so the assembler automatically selects the
> encoding based on operand constraints.
>
> To preserve instruction definitions through linking, the assembler emits
> a metadata record for each .extInstruction into a COMDAT ELF section
> named .riscvapex.<fmt>.<major>.<sub_opcode>.  The disassembler reads
> these sections at startup, reconstructs the opcode entries, and falls
> back to them when the standard opcode table produces no match.
>
> The directive syntax, instruction formats, and metadata representation
> in this RISCV-V APEX port are intentionally aligned with existing
> proprietary compiler and architecture to maintain compatibility across
> toolchains.
>
> Patch 1 adds the assembler: .extInstruction parsing, validation,
> encoding, and metadata emission, along with documentation and tests
> (4 positive + 10 negative cases).
>
> Patch 2 adds the disassembler: metadata deserialization, dynamic opcode
> reconstruction, and APEX-specific decode path, plus 2 linker tests
> verifying metadata sections survive linking.
>
> Tested with the gas, ld and gdb testsuites for riscv-elf targets.
>
> Luis Silva (2):
>   RISC-V: Add ARC-V APEX assembler support
>   RISC-V: Add ARC-V APEX disassembler support
>
>  gas/config/tc-riscv.c                         | 631 ++++++++++++++++++
>  gas/doc/c-riscv.texi                          |  53 ++
>  gas/testsuite/gas/riscv/x-arcv-apex-01.d      |  18 +
>  gas/testsuite/gas/riscv/x-arcv-apex-01.s      |  19 +
>  gas/testsuite/gas/riscv/x-arcv-apex-02.d      |  13 +
>  gas/testsuite/gas/riscv/x-arcv-apex-02.s      |   6 +
>  gas/testsuite/gas/riscv/x-arcv-apex-03.d      |  46 ++
>  gas/testsuite/gas/riscv/x-arcv-apex-04.d      |  15 +
>  gas/testsuite/gas/riscv/x-arcv-apex-04.s      |  10 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-01.d |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-01.l |   2 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-01.s |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-02.d |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-02.l |   5 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-02.s |   3 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-03.d |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-03.l |   9 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-03.s |  12 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-04.d |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-04.l |   3 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-04.s |   2 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-05.d |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-05.l |   3 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-05.s |   3 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-06.d |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-06.l |   7 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-06.s |   7 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-07.d |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-07.l |   9 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-07.s |   9 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-08.d |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-08.l |   5 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-08.s |   7 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-09.d |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-09.l |   3 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-09.s |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-10.d |   1 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-10.l |   3 +
>  gas/testsuite/gas/riscv/x-arcv-apex-fail-10.s |   2 +
>  include/opcode/riscv.h                        |  74 ++
>  ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp    |  10 +
>  ld/testsuite/ld-riscv-elf/x-arcv-apex-01-a.s  |   8 +
>  ld/testsuite/ld-riscv-elf/x-arcv-apex-01-b.s  |  21 +
>  ld/testsuite/ld-riscv-elf/x-arcv-apex-01-c.s  |  21 +
>  ld/testsuite/ld-riscv-elf/x-arcv-apex-01.d    |  32 +
>  ld/testsuite/ld-riscv-elf/x-arcv-apex-02.d    |  36 +
>  opcodes/riscv-dis.c                           | 269 ++++++++
>  opcodes/riscv-opc.c                           | 140 ++++
>  48 files changed, 1528 insertions(+)
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-01.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-01.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-02.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-02.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-03.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-04.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-04.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-01.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-01.l
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-01.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-02.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-02.l
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-02.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-03.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-03.l
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-03.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-04.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-04.l
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-04.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-05.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-05.l
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-05.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-06.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-06.l
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-06.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-07.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-07.l
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-07.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-08.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-08.l
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-08.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-09.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-09.l
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-09.s
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-10.d
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-10.l
>  create mode 100644 gas/testsuite/gas/riscv/x-arcv-apex-fail-10.s
>  create mode 100644 ld/testsuite/ld-riscv-elf/x-arcv-apex-01-a.s
>  create mode 100644 ld/testsuite/ld-riscv-elf/x-arcv-apex-01-b.s
>  create mode 100644 ld/testsuite/ld-riscv-elf/x-arcv-apex-01-c.s
>  create mode 100644 ld/testsuite/ld-riscv-elf/x-arcv-apex-01.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/x-arcv-apex-02.d
>
> --
> 2.34.0
  
Luis Silva May 25, 2026, 3:24 p.m. UTC | #2
>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.

>Do you have interested to present that and create a PR to https://urldefense.com/v3/__https://github.com/riscv-non-isa/riscv-c-api-doc__;!!A4F2R9G_pg!aYag73swD7mc2NMIkBCavNj1MeY51Dbt3JrAzKctCsxFbxWIGeOCdwEAwCytpP0sRiJcAFkiF4WFrHxWx37Ms8k$  to >start the discussion? also it would be nice if you can present that on toolchain sig meeting :)

Repeating my reply on gcc mailing list here:

Hi Kito,

Thank you for the positive feedback! I'd be happy to present this at
the toolchain SIG meeting and have further discussion.

Best regards,
Luis