Skip to content

arcv: Add APEX support. #160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 26 commits into
base: arc-2025.06
Choose a base branch
from
Open

arcv: Add APEX support. #160

wants to merge 26 commits into from

Conversation

luismgsilva
Copy link
Member

Thanks for taking the time to contribute to GCC! Please be advised that if you are
viewing this on github.com, that the mirror there is unofficial and unmonitored.
The GCC community does not use github.com for their contributions. Instead, we use
a mailing list ([email protected]) for code submissions, code reviews, and
bug reports. Please send patches there instead.

@luismgsilva luismgsilva self-assigned this Jul 14, 2025
@luismgsilva luismgsilva marked this pull request as ready for review July 16, 2025 08:12
@luismgsilva luismgsilva force-pushed the luis/apex branch 3 times, most recently from 75521b9 to dec1e1a Compare July 17, 2025 09:10
Implements support for a new pragma of the form:

    #pragma intrinsic(fn_name, "insn_name", opcode, "format"...)

This pragma registers a user-defined intrinsic to be treated
as built-in APEX instructions during compilation.  Parsing
its name, instruction mnemonic, opcode and a set of optional
format specifiers ("XD", "XS", "XI", "XC").

Signed-off-by: Luis Silva <[email protected]>
Introduce `arcv_apex_lookup_function` to return the function declaration
corresponding to a string name provided via the #pragma intrinsic
directive.  It performs a scoped lookup, verifies that the name refers
to a function, and issues an error if not declared.

Signed-off-by: Luis Silva <[email protected]>
Adds `arcv_apex_set_insn_operand_flags`, which examines the return type
and arguments of a built-in function to determine the appropriate APEX
operand flags.  A non-void return type sets APEX_DEST, and up to two
arguments set APEX_SRC0 and APEX_SRC1.

Emits an error if the function has more than two arguments.

Signed-off-by: Luis Silva <[email protected]>
Adds `arcv_apex_resolve_insn_format`, which computes a concrete APEX
format (XD, XS, XI or XC) when no explicit format is provided. The
selection is based on the operand configuration and opcode value.

Also introduces `APEX_OPCODE_FIELD_MAX` and operand signature masks
to guide format resolution based on accepted operand patterns.

Signed-off-by: Luis Silva <[email protected]>
Introduces `arcv_apex_validate_insn_format`, which checks whether a
specified APEX instruction format is valid given the opcode and
operand layout. The validation includes:

- Ensuring the opcode falls within the allowed range for the format.
- Verifying the number of scalar operands is appropriate.
- Enforcing format-specific constraints such as return value presence.

The supported format rules are encoded in a `format_rule` table,
covering XD, XS, XI and XC.

Signed-off-by: Luis Silva <[email protected]>
Adds `arcv_apex_print_insn_section`, which prints
`.extInstruction` assembly sections for APEX instructions.
This function determines the appropriate formats and operand
annotations to output based on the insn_format bitmask.

The output helps the assembler and disassembler recognize supported
instruction formats, including operand roles (void, no_src0, no_src1)
and format classes (XD, XS, XI, XC).

Signed-off-by: Luis Silva <[email protected]>
Introduce new ARC-V APEX constraints to validate operand values and
instruction format support for user-defined builtins:

  - Add constraints "B8" for 8-bit signed immediates (-128 to 127).
  - Add format-specific constraints "xAVpXD", "xAVpXS", "xAVpXI" and
    "xAVpXC" to check whether a given APEX instruction (by subcode)
    supports the respective instruction format.

Also implement "arcv_apex_format_supports_p ()" in "riscv-builtins.cc",
which performs a bitmask check against the stored instruction format
flags for a given APEX builtin. Used during instruction selection to
ensure only applicable patterns match.

Signed-off-by: Luis Silva <[email protected]>
Defines new `define_insn` patterns to support ARC-V APEX instructions
across all supported formats (`XI`, `XS`, `XC`, `XD`).  These patterns
emit custom assembly using the `arcv_apex_get_insn_name` hook to
dynamically resolve the instruction mnemonic from the subcode operand.

Covers the following instruction forms:

- `insn`: used by "XD" (no operands)
- `insn src0`: used by "XI","XD" (immediate or register)
- `insn src0, src1`: used by "XS","XD" (register or mixed with immediate)
- `insn dest`: used by "XD"
- `insn dest, src0`: used by "XI","XD"
- `insn dest, src0, imm/src1`: used by "XS","XC","XD"

Signed-off-by: Luis Silva <[email protected]>
Adds `arcv_apex_get_icode`, a helper that selects the appropriate
`insn_code` based on the operand layout encoded in `insn_format`.
It distinguishes among patterns like `void`, `src0`, `dest,src0`
and `dest,src0,src1` and maps them to the corresponding
`CODE_FOR_riscv_arcv_apex_*` enum used in RTL generation.

Signed-off-by: Luis Silva <[email protected]>
Introduce infrastructure to register user-defined APEX intrinsics as
RISC-V built-in functions during pragma handling. This includes:

- Adding the arcv_apex_builtin_description structure and related data
  to store metadata for up to 384 APEX instructions.
- Implementing arcv_apex_init_builtin(), which validates and resolves
  its instruction format, determines its internal instruction code
  (icode), modifies an existing function declaration as a built-in
  function, and updates the function declaration with custom function
  code.
- Hooking up arcv_apex_init_builtin() in arcv_apex_pragma_intrinsic().
- Extending riscv_builtin_class with RISCV_BUILTIN_APEX and updating
  RISCV_BUILTIN_SHIFT to 2.

This allows the compiler to recognize and process APEX intrinsics
defined by users via pragma directives as first-class built-in functions.

Signed-off-by: Luis Silva <[email protected]>
This patch extends "riscv_expand_builtin_direct" to optionally accept
and attach a subcode operand for APEX builtins. A new "has_subcode_p"
flag determines whether a constant RTL operand for the subcode should
be added to the operand list.

The subcode is used to extract the instruction name from
"arcv_apex_builtins" once a pattern is selected in the machine description
(see "arcv_apex_get_insn_name (rtx op)").

Also updates "riscv_check_builtin_call" and
"riscv_resolve_overloaded_builtin" to handle the new
"RISCV_BUILTIN_APEX" class.

Signed-off-by: Luis Silva <[email protected]>
Introduce "unspec_volatile" to handle APEX instructions that have
side effects and must not be optimized away by the compiler.
When an instruction is defined with the "side_effect" attribute via
preventing optimizations such as common subexpression elimination,
loop-invariant motion, or dead code elimination.

Instructions with no destination register are treated as volatile.

Signed-off-by: Luis Silva <[email protected]>
Use "c_register_pragma_with_expansion()" instead of "c_register_pragma()" to
ensure that "arcv_apex_pragma_intrinsic" is invoked with arguments that
have been macro-expanded.

This allows users to define APEX intrinsic names or parameters using
macros in pragma directives, ensuring the handler processes the
expanded values  rather than raw macro identifiers.

Signed-off-by: Luis Silva <[email protected]>
GCC selects the "define_expand" based on the operand layout of the
function declaration.
Since the declaration may use different orders or types of operands, we
take full advantage of GCC’s internal instruction recognizer to match
RTL expressions with the correct pattern in the machine description.

During the "define_expand", the compiler generates a generic RTL using
an "UNSPEC" code to uniquely identify a family of custom instructions
along with their operands.
At this stage, it's not yet a real instruction — it's an abstract
placeholder tagged with a unique "UNSPEC" code.

Later, during instruction selection, GCC calls "recog", which matches
this RTL expression to the appropriate "define_insn" based on:

- The "UNSPEC" code (acts as a unique identifier);
- Operand modes (e.g., "SI", `DI`, etc.);
- Operand predicates and constraints.

If all conditions match, GCC selects the correct "define_insn", and code
generation proceeds accordingly.

To cover all valid combinations of operand types, the "define_insn" uses
mode iterators (like "DM", "S0M", "S1M"), allowing it to generate all
required mode variants from a single pattern template.

Signed-off-by: Luis Silva <[email protected]>
Add validation for immediate arguments in APEX intrinsic calls
that do not support the APEX_XD format. This check is performed
during riscv_expand_builtin_direct, where the actual values of
the current RTL expression are available.

The validation ensures that the argument is a constant integer
and falls within the correct range:

- For APEX_XI and APEX_XC formats: signed 12-bit [-2048, 2047]
- For APEX_XS format: signed 8-bit [-128, 127]

Report an error if the value does not meet the previous checks.

Signed-off-by: Luis Silva <[email protected]>
When an APEX instruction does not have a user-defined format specified
via pragma, its format is resolved based on operand flags and opcode.  In
these cases, this patch appends an "i" suffix to the instruction name to
distinguish it from the XD format.  While XD instructions and
immediate-based formats (XI, XS, XC) may have the same number of
operands, XD uses only registers, whereas the others include at least
one immediate operand.

Signed-off-by: Luis Silva <[email protected]>
…insn format.

Add a check to detect when a new APEX intrinsic specifies an opcode
value that overlaps with an already registered intrinsic, considering
only the lower 4 bits of the insn format (XD, XS, XI, XC). Emit an
error in such cases to prevent opcode conflicts at runtime.

Signed-off-by: Luis Silva <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants