Skip to content

Commit e91b1cc

Browse files
committed
arcv: apex: Add APEX intrinsic built-in registration mechanism.
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]>
1 parent a63fa85 commit e91b1cc

File tree

3 files changed

+102
-3
lines changed

3 files changed

+102
-3
lines changed

gcc/config/riscv/riscv-builtins.cc

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,35 @@ static GTY(()) int riscv_builtin_decl_index[NUM_INSN_CODES];
236236

237237
tree riscv_float16_type_node = NULL_TREE;
238238

239+
struct arcv_apex_builtin_description {
240+
/* The code of the main .md file instruction. See riscv_builtin_type
241+
for more information. */
242+
enum insn_code icode;
243+
244+
/* The name of the built-in function. */
245+
const char *name;
246+
247+
/* The name of the built-in instruction. */
248+
const char *insn_name;
249+
250+
/* Specifies how the function should be expanded. */
251+
enum riscv_builtin_type builtin_type;
252+
253+
/* Specifies the instruction format. See "apex_insn_format" enum
254+
for more details. */
255+
unsigned int insn_formats;
256+
};
257+
258+
/* The XD-type has 8 function bits encoding up to 256 instructions.
259+
The XS-type has 6 function bits encoding up to 64 instructions.
260+
Both the XI-type and the XC-type have 5 function bits each encoding up
261+
to 32 instructions respectively. Thus giving a total of 384 possible
262+
different instructions. */
263+
static const int arcv_apex_builtins_limit = 384;
264+
static struct arcv_apex_builtin_description
265+
arcv_apex_builtins[arcv_apex_builtins_limit];
266+
static int arcv_apex_builtin_index = 0;
267+
239268
/* Return the function type associated with function prototype TYPE. */
240269

241270
static tree
@@ -770,3 +799,65 @@ arcv_apex_get_icode (unsigned insn_format)
770799
return CODE_FOR_nothing;
771800
}
772801
}
802+
803+
/* Initialize a RISC-V APEX built-in function.
804+
805+
This function is invoked for each user-defined APEX intrinsic declared via
806+
a pragma. It processes the parased, resolves the appropriate instruction
807+
format, validates it and prints the corresponding .extInstruction section
808+
for the assembler.
809+
810+
It then determines the internal instruction code (icode) and categorizes the
811+
built-in as either with or without a destination operand. The function
812+
stores the resulting instruction metadata into the "arcv_apex_builtins"
813+
array, modifies the function declaration "fndecl" to be recognized as a
814+
built-in (BUILT_IN_MD), and encodes a custom function code for use
815+
during later compiler stages.
816+
817+
Each call increments the global built-in index to allow defining multiple
818+
intrinsics in sequence. */
819+
820+
void
821+
arcv_apex_init_builtin (tree fndecl, const char *fn_name,
822+
const char *insn_name, unsigned int insn_formats,
823+
int opcode)
824+
{
825+
/* Update operand flags based on the function declaration. */
826+
insn_formats = arcv_apex_set_insn_operand_flags (insn_formats, fndecl);
827+
if (insn_formats == 0xFFFFFFFF)
828+
return;
829+
830+
/* Resolve the instruction format:
831+
If the user did not specify an instruction format at pragma level,
832+
infer the concrete format based on opcode and operand flags; otherwise,
833+
leave it as is. */
834+
insn_formats = arcv_apex_resolve_insn_format (insn_formats, opcode);
835+
836+
/* Validate the format is allowed for this instruction. */
837+
arcv_apex_validate_insn_format (fn_name, insn_formats, opcode);
838+
839+
/* Print .extInstruction section about APEX instruction. */
840+
arcv_apex_print_insn_section (insn_name, opcode, insn_formats);
841+
842+
/* Determine the internal instruction code (icode). */
843+
enum insn_code icode = arcv_apex_get_icode (insn_formats);
844+
845+
/* Determine whether this builtin has a destination operand. */
846+
enum riscv_builtin_type builtin_type
847+
= (insn_formats & APEX_DEST) ? RISCV_BUILTIN_DIRECT :
848+
RISCV_BUILTIN_DIRECT_NO_TARGET;
849+
850+
/* Store APEX insn information. */
851+
arcv_apex_builtins[arcv_apex_builtin_index]
852+
= { icode, fn_name, insn_name, builtin_type, insn_formats };
853+
854+
/* Modify the prototype type as built-in. */
855+
fndecl->function_decl.built_in_class = BUILT_IN_MD;
856+
857+
/* Modify the prototype function code to match the index
858+
in "riscv_apex_builtins" with a mask for APEX only insns. */
859+
fndecl->function_decl.function_code
860+
= (arcv_apex_builtin_index << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_APEX;
861+
862+
arcv_apex_builtin_index++;
863+
}

gcc/config/riscv/riscv-c.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,9 @@ arcv_apex_pragma_intrinsic (cpp_reader *)
315315

316316
/* Lookup the user-defined function declaration of the APEX intrinsic. */
317317
tree fndecl = arcv_apex_lookup_function (fn_name);
318+
319+
/* Register the specified function as an APEX intrinsic. */
320+
arcv_apex_init_builtin (fndecl, fn_name, insn_name, insn_formats, opcode);
318321
}
319322

320323
static int

gcc/config/riscv/riscv-protos.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -732,14 +732,17 @@ bool splat_to_scalar_move_p (rtx *);
732732
/* We classify builtin types into two classes:
733733
1. General builtin class which is defined in riscv_builtins.
734734
2. Vector builtin class which is a special builtin architecture
735-
that implement intrinsic short into "pragma". */
735+
that implement intrinsic short into "pragma".
736+
3. Apex builtin class which is user-defined custom instruction
737+
via "pragma intrinsic()". */
736738
enum riscv_builtin_class
737739
{
738740
RISCV_BUILTIN_GENERAL,
739-
RISCV_BUILTIN_VECTOR
741+
RISCV_BUILTIN_VECTOR,
742+
RISCV_BUILTIN_APEX
740743
};
741744

742-
const unsigned int RISCV_BUILTIN_SHIFT = 1;
745+
const unsigned int RISCV_BUILTIN_SHIFT = 2;
743746

744747
/* Mask that selects the riscv_builtin_class part of a function code. */
745748
const unsigned int RISCV_BUILTIN_CLASS = (1 << RISCV_BUILTIN_SHIFT) - 1;
@@ -770,6 +773,8 @@ extern bool arcv_micro_arch_supports_fusion_p (void);
770773
extern void arcv_apex_print_insn_section (const char *, int, unsigned int);
771774
extern const char* arcv_apex_get_insn_name (rtx);
772775
extern bool arcv_apex_format_supports_p (unsigned int, unsigned int);
776+
extern void arcv_apex_init_builtin (tree, const char *, const char *,
777+
unsigned int, int);
773778

774779
#ifdef RTX_CODE
775780
extern const char*

0 commit comments

Comments
 (0)