mirror of
https://github.com/pound-emu/pound.git
synced 2025-12-13 13:37:02 +00:00
Introduces IR instruction management, including instruction_t and instruction_list_t definitions and their implementations. It also added const-correctness to the value_t API. Signed-off-by: Ronald Caesar <github43132@proton.me>
175 lines
6 KiB
C++
175 lines
6 KiB
C++
#ifndef POUND_JIT_IR_INSTRUCTION_H
|
|
#define POUND_JIT_IR_INSTRUCTION_H
|
|
|
|
#include "opcode.h"
|
|
#include "value.h"
|
|
#include <stddef.h>
|
|
|
|
namespace pound::jit::ir {
|
|
// Maximum number of arguments an IR instruction can have.
|
|
#define MAX_IR_ARGS 4
|
|
|
|
/*!
|
|
* Represents a single instruction in the IR layer.
|
|
*
|
|
* Each instruction node encapsulates an opcode, its arguments, and pointers to
|
|
* form an intrusive double-linked list.
|
|
*/
|
|
typedef struct instruction_t
|
|
{
|
|
// The opcode for this instruction.
|
|
opcode_t opcode;
|
|
|
|
// An array of arguments for this instruction.
|
|
value_t args[MAX_IR_ARGS];
|
|
|
|
// Pointer to the next instruction in the intrusive list.
|
|
struct instruction_t *next;
|
|
|
|
// Pointer to the previous instruction the intrusive list.
|
|
struct instruction_t *previous;
|
|
} instruction_t;
|
|
|
|
/*!
|
|
* @brief Represents a double-linked list of IR instructions.
|
|
*
|
|
* This structure holds the head and tail pointers of an intrusive list
|
|
* composed of `instruction_t` nodes. It is used to store sequences
|
|
*/
|
|
typedef struct
|
|
{
|
|
// Pointer to the first instruction in the list.
|
|
instruction_t *head;
|
|
|
|
// Pointer to the last instruction in the list.
|
|
instruction_t *tail;
|
|
} instruction_list_t;
|
|
|
|
/*!
|
|
* @brief Gets a pointer to the argument at a specific index.
|
|
*
|
|
* @param instruction Pointer to the IR instruction.
|
|
* @param arg_index The index of the argument to retrieve.
|
|
*
|
|
* @return A constant pointer to the argument at the specified index.
|
|
* @pre `instruction` must not be NULL
|
|
* @pre `arg_index` must be less than `MAX_IR_ARGS`.
|
|
*/
|
|
const value_t* instruction_get_arg (const instruction_t *instruction, const size_t arg_index);
|
|
|
|
/*!
|
|
* Retrieves a U64 argument from an instruction.
|
|
*
|
|
* @param instruction Pointer to the IR instruction.
|
|
* @apram arg_index The index of the argument to retrieve.
|
|
*
|
|
* @return The U64 value of the argument.
|
|
* @pre `instruction` must not be NULL.
|
|
* @pre `arg_index` must be less than `MAX_IR_ARGS`.
|
|
* @pre The argument at `arg_index` must be of type `IR_TYPE_U64`.
|
|
*/
|
|
const uint64_t instruction_get_arg_u64(const instruction_t *instruction, const size_t arg_index);
|
|
|
|
/*!
|
|
* @brief Retrieves a U32 argument from an instruction.
|
|
*
|
|
* @param instruction Pointer to the IR instruction.
|
|
* @param arg_index The index of the argument to retrieve.
|
|
*
|
|
* @return The U32 value of the argument.
|
|
* @pre `instruction` must not be NULL.
|
|
* @pre `arg_index` must be less than `MAX_IR_ARGS`.
|
|
* @pre The argument at `arg_index` must be of type `IR_TYPE_U32`.
|
|
*/
|
|
const uint32_t instruction_get_arg_u32(const instruction_t *instruction, const size_t arg_index);
|
|
|
|
/*!
|
|
* Retrives a U8 argument from an instruction.
|
|
*
|
|
* @param instruction Pointer to the IR instruction.
|
|
* @param arg_index The index of the argument to retrieve.
|
|
*
|
|
* @return The U8 value of the argument.
|
|
* @pre `instruction` must not be NULL.
|
|
* @pre `arg_index` must be less than `MAX_IR_ARGS`.
|
|
* @pre The argument at `arg_index` must be of type `IR_TYPE_U8`.
|
|
*/
|
|
const uint8_t instruction_get_arg_u8(const instruction_t *instruction, const size_t arg_index);
|
|
|
|
/*!
|
|
* @brief Retrieves a U1 (boolean) argument from an instruction.
|
|
*
|
|
* @param instruction Pointer to the IR instruction.
|
|
* @param arg_index The index of the argument to retrieve.
|
|
*
|
|
* @return The boolean value of the argument.
|
|
* @pre `instruction` must not be NULL.
|
|
* @pre `arg_index` must be less than `MAX_IR_ARGS`.
|
|
* @pre The argument at `arg_index` must be of type `IR_TYPE_U1`.
|
|
*/
|
|
const bool instruction_get_arg_u1(const instruction_t *instruction, const size_t arg_index);
|
|
|
|
/*!
|
|
* @brief Retrieves an A32 register identifier argument from an instruction.
|
|
*
|
|
* @param instruction Pointer to the IR instruction.
|
|
* @param arg_index The index of the argument to retrieve.
|
|
*
|
|
* @return The `a32_register_t` identifier.
|
|
* @pre `instruction` must not be NULL.
|
|
* @pre `arg_index` must be less than `MAX_IR_ARGS`.
|
|
* @pre The argument at `arg_index` must be of type `IR_TYPE_A32_REGISTER`.
|
|
*/
|
|
const pound::jit::a32_register_t instruction_get_arg_a32_register(const instruction_t *instruction, const size_t arg_index);
|
|
|
|
/*!
|
|
* @brief Gets the return type of an instruction based on its opcode.
|
|
*
|
|
* @param instruction Pointer to the IR instruction.
|
|
*
|
|
* @return The `type_t` that this instruction's opcode returns.
|
|
* @pre `instruction` must not be NULL.
|
|
* @pre `instruction->opcode` must be a valid opcode index (less than `NUM_OPCODE`).
|
|
*/
|
|
const type_t instruction_get_return_type (const instruction_t *instruction);
|
|
|
|
|
|
/*!
|
|
* @brief Gets the name of an instruction's opcode as a C-string.
|
|
*
|
|
* @param instruction Pointer to the IR instruction.
|
|
*
|
|
* @return A constant C-string containing the opcode's name.
|
|
* @pre `instruction` must not be NULL.
|
|
* @pre `instruction->opcode` must be a valid opcode index (less than `NUM_OPCODE`).
|
|
* @pre The global `g_opcodes` array must be initialized and accessible.
|
|
*/
|
|
const char* instruction_get_opcode_name(const instruction_t *instruction);
|
|
|
|
/*!
|
|
* @brief Appends an instruction to the tail of an instruction list.
|
|
*
|
|
* The instruction is added to the end of the list. If the list is empty,
|
|
* the instruction becomes both the head and the tail.
|
|
*
|
|
* @param list Pointer to the instruction list to modify.
|
|
* @param instruction Pointer to the `instruction_t` node to append.
|
|
*
|
|
* @pre `list` must not be NULL.
|
|
* @pre `instruction` must not be NULL.
|
|
*/
|
|
void instruction_list_append (instruction_list_t *list, instruction_t *instruction);
|
|
|
|
/*!
|
|
* @brief Removes an instruction from an instruction list.
|
|
*
|
|
* @param list Pointer to the instruction list to modify.
|
|
* @param instruction Pointer to the `instruction_t` node to remove.
|
|
*
|
|
* @pre `list` must not be NULL.
|
|
* @pre `instruction` must not be NULL.
|
|
* @pre `instruction` must be a member of `list`.
|
|
*/
|
|
void instruction_list_remove (instruction_list_t *list, instruction_t *instruction);
|
|
}
|
|
#endif // POUND_JIT_IR_INSTRUCTION_H
|