Compare commits

...

2 commits

Author SHA1 Message Date
Ronald Caesar
0011bb7825
jit/ir: remove the prefix p_ from pointers
Although this is mandated in the Barr C style guide, I find this
specific rule uneccesarry and tedious.

Signed-off-by: Ronald Caesar <github43132@proton.me>
2025-11-27 16:03:01 -04:00
Ronald Caesar
d61fbe3514
jit/ir: Remove instruction linked list
The linked list was implemented to store instructions in a basic block.
Instructions will now be stored in arrays to keep logic simple and
straight-foward.

Signed-off-by: Ronald Caesar <github43132@proton.me>
2025-11-27 15:59:16 -04:00
4 changed files with 78 additions and 174 deletions

View file

@ -112,51 +112,4 @@ instruction_get_opcode_name (const instruction_t *instruction)
return name;
}
void
instruction_list_append (instruction_list_t *list, instruction_t *instruction)
{
PVM_ASSERT(nullptr != list);
PVM_ASSERT(nullptr != instruction);
instruction->next = nullptr;
instruction->previous = list->tail;
if (nullptr != list->tail)
{
list->tail->next = instruction;
}
else
{
list->head = instruction;
}
list->tail = instruction;
}
void
instruction_list_remove (instruction_list_t *list, instruction_t *instruction)
{
PVM_ASSERT(nullptr != list);
PVM_ASSERT(nullptr != instruction);
if (nullptr != instruction->previous)
{
instruction->previous->next = instruction->next;
}
else
{
list->head = instruction->next;
}
if (nullptr != instruction->next)
{
instruction->next->previous = instruction->previous;
}
else
{
list->tail = instruction->previous;
}
instruction->next = nullptr;
instruction->previous = nullptr;
}
}

View file

@ -22,29 +22,8 @@ typedef struct instruction_t
// 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.
*
@ -147,33 +126,5 @@ type_t instruction_get_return_type(instruction_t *instruction);
* @pre The global `g_opcodes` array must be initialized and accessible.
*/
const char *instruction_get_opcode_name(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

View file

@ -10,50 +10,50 @@ namespace pound::jit::ir {
*/
void
value_init (value_t *p_value)
value_init (value_t *value)
{
PVM_ASSERT(nullptr != p_value);
p_value->type = IR_TYPE_VOID;
PVM_ASSERT(nullptr != value);
value->type = IR_TYPE_VOID;
}
void
value_init_from_u64 (value_t *p_value, const uint64_t u64)
value_init_from_u64 (value_t *value, const uint64_t u64)
{
PVM_ASSERT(nullptr != p_value);
p_value->type = IR_TYPE_U64;
p_value->inner.immediate_u64 = u64;
PVM_ASSERT(nullptr != value);
value->type = IR_TYPE_U64;
value->inner.immediate_u64 = u64;
}
void
value_init_from_u32 (value_t *p_value, const uint32_t u32)
value_init_from_u32 (value_t *value, const uint32_t u32)
{
PVM_ASSERT(nullptr != p_value);
p_value->type = IR_TYPE_U32;
p_value->inner.immediate_u32 = u32;
PVM_ASSERT(nullptr != value);
value->type = IR_TYPE_U32;
value->inner.immediate_u32 = u32;
}
void
value_init_from_u8 (value_t *p_value, const uint8_t u8)
value_init_from_u8 (value_t *value, const uint8_t u8)
{
PVM_ASSERT(nullptr != p_value);
p_value->type = IR_TYPE_U8;
p_value->inner.immediate_u8 = u8;
PVM_ASSERT(nullptr != value);
value->type = IR_TYPE_U8;
value->inner.immediate_u8 = u8;
}
void
value_init_from_u1 (value_t *p_value, const bool u1)
value_init_from_u1 (value_t *value, const bool u1)
{
PVM_ASSERT(nullptr != p_value);
p_value->type = IR_TYPE_U1;
p_value->inner.immediate_u1 = u1;
PVM_ASSERT(nullptr != value);
value->type = IR_TYPE_U1;
value->inner.immediate_u1 = u1;
}
void
value_init_from_a32_register (value_t *p_value, const a32_register_t reg)
value_init_from_a32_register (value_t *value, const a32_register_t reg)
{
PVM_ASSERT(nullptr != p_value);
p_value->type = IR_TYPE_A32_REGISTER;
p_value->inner.immediate_a32_register = reg;
PVM_ASSERT(nullptr != value);
value->type = IR_TYPE_A32_REGISTER;
value->inner.immediate_a32_register = reg;
}
/*
@ -63,37 +63,37 @@ value_init_from_a32_register (value_t *p_value, const a32_register_t reg)
*/
uint64_t
value_get_u64 (const value_t *p_value)
value_get_u64 (const value_t *value)
{
PVM_ASSERT(IR_TYPE_U64 == p_value->type);
return p_value->inner.immediate_u64;
PVM_ASSERT(IR_TYPE_U64 == value->type);
return value->inner.immediate_u64;
}
uint32_t
value_get_u32 (const value_t *p_value)
value_get_u32 (const value_t *value)
{
PVM_ASSERT(IR_TYPE_U32 == p_value->type);
return p_value->inner.immediate_u32;
PVM_ASSERT(IR_TYPE_U32 == value->type);
return value->inner.immediate_u32;
}
uint8_t
value_get_u8 (const value_t *p_value)
value_get_u8 (const value_t *value)
{
PVM_ASSERT(IR_TYPE_U8 == p_value->type);
return p_value->inner.immediate_u8;
PVM_ASSERT(IR_TYPE_U8 == value->type);
return value->inner.immediate_u8;
}
bool
value_get_u1 (const value_t *p_value)
value_get_u1 (const value_t *value)
{
PVM_ASSERT(IR_TYPE_U1 == p_value->type);
return p_value->inner.immediate_u1;
PVM_ASSERT(IR_TYPE_U1 == value->type);
return value->inner.immediate_u1;
}
pound::jit::a32_register_t
value_get_a32_register (const value_t *p_value)
value_get_a32_register (const value_t *value)
{
PVM_ASSERT(IR_TYPE_A32_REGISTER == p_value->type);
return p_value->inner.immediate_a32_register;
PVM_ASSERT(IR_TYPE_A32_REGISTER == value->type);
return value->inner.immediate_a32_register;
}
}

View file

@ -46,56 +46,56 @@ typedef struct
/*!
* @brief Initializes a `value_t` instance to a default/void state.
*
* @param p_value Pointer to the `value_t` instance to initialize.
* @post The `p_value`'s `type` will be set to `IR_TYPE_VOID`.
* @param value Pointer to the `value_t` instance to initialize.
* @post The `value`'s `type` will be set to `IR_TYPE_VOID`.
* The contents of its `inner` union are considered undefined
* for a void value.
*/
void value_init(value_t *p_value);
void value_init(value_t *value);
/*!
* @brief Initializes a `value_t` instance to hold an unsigned 64-bit immediate
* value.
*
* @param p_value Pointer to the `value_t` instance to initialize.
* @param value Pointer to the `value_t` instance to initialize.
* @param u64 The 64-bit unsigned immediate value to store.
* @post The `p_value`'s `type` will be set to `IR_TYPE_U64` and its
* @post The `value`'s `type` will be set to `IR_TYPE_U64` and its
* `inner.immediate_u64` member will contain `u64`.
*/
void value_init_from_u64(value_t *p_value, uint64_t u64);
void value_init_from_u64(value_t *value, uint64_t u64);
/*!
* @brief Initializes a `value_t` instance to hold an unsigned 32-bit immediate
* value.
*
* @param p_value Pointer to the `value_t` instance to initialize.
* @param value Pointer to the `value_t` instance to initialize.
* @param u32 The 32-bit unsigned immediate value to store.
* @post The `p_value`'s `type` will be set to `IR_TYPE_U32` and its
* @post The `value`'s `type` will be set to `IR_TYPE_U32` and its
* `inner.immediate_u32` member will contain `u32`.
*/
void value_init_from_u32(value_t *p_value, uint32_t u32);
void value_init_from_u32(value_t *value, uint32_t u32);
/*!
* @brief Initializes a `value_t` instance to hold an unsigned 8-bit immediate
* value.
*
* @param p_value Pointer to the `value_t` instance to initialize.
* @param value Pointer to the `value_t` instance to initialize.
* @param u8 The 8-bit unsigned immediate value to store.
* @post The `p_value`'s `type` will be set to `IR_TYPE_U8` and its
* @post The `value`'s `type` will be set to `IR_TYPE_U8` and its
* `inner.immediate_u8` member will contain `u8`.
*/
void value_init_from_u8(value_t *p_value, uint8_t u8);
void value_init_from_u8(value_t *value, uint8_t u8);
/*!
* @brief Initializes a `value_t` instance to hold a 1-bit boolean immediate
* value.
*
* @param p_value Pointer to the `value_t` instance to initialize.
* @param value Pointer to the `value_t` instance to initialize.
* @param u1 The boolean (1-bit) immediate value to store.
* @post The `p_value`'s `type` will be set to `IR_TYPE_U1` and its
* @post The `value`'s `type` will be set to `IR_TYPE_U1` and its
* `inner.immediate_u1` member will contain `u1`.
*/
void value_init_from_u1(value_t *p_value, bool u1);
void value_init_from_u1(value_t *value, bool u1);
/*!
* @brief Initializes a `value_t` instance to hold an A32 register identifier.
@ -103,67 +103,67 @@ void value_init_from_u1(value_t *p_value, bool u1);
* This function stores the *identity* of an A32 register (e.g., R0, SP, PC)
* within the `value_t`. It does not store the *content* of that register.
*
* @param p_value Pointer to the `value_t` instance to initialize.
* @param value Pointer to the `value_t` instance to initialize.
* @param reg The A32 register identifier (of type `a32_register_t`) to store.
* @post The `p_value`'s `type` will be set to `IR_TYPE_A32_REGISTER` and its
* @post The `value`'s `type` will be set to `IR_TYPE_A32_REGISTER` and its
* `inner.immediate_a32_register` member will contain `reg`.
*/
void value_init_from_a32_register(value_t *p_value, a32_register_t reg);
void value_init_from_a32_register(value_t *value, a32_register_t reg);
/*!
* @brief Retrieves an unsigned 64-bit immediate value from a `value_t`.
*
* @pre The `p_value` must be of type `IR_TYPE_U64`.
* @param p_value Pointer to the `value_t` instance.
* @retval uint64_t The 64-bit unsigned immediate value stored in `p_value`.
* @pre The `value` must be of type `IR_TYPE_U64`.
* @param value Pointer to the `value_t` instance.
* @retval uint64_t The 64-bit unsigned immediate value stored in `value`.
* @warning Calling this function on a `value_t` not of type `IR_TYPE_U64`
* results in undefined behavior.
*/
uint64_t value_get_u64(const value_t *p_value);
uint64_t value_get_u64(const value_t *value);
/*!
* @brief Retrieves an unsigned 32-bit immediate value from a `value_t`.
*
* @pre The `p_value` must be of type `IR_TYPE_U32`.
* @param p_value Pointer to the `value_t` instance.
* @retval uint32_t The 32-bit unsigned immediate value stored in `p_value`.
* @pre The `value` must be of type `IR_TYPE_U32`.
* @param value Pointer to the `value_t` instance.
* @retval uint32_t The 32-bit unsigned immediate value stored in `value`.
* @warning Calling this function on a `value_t` not of type `IR_TYPE_U32`
* results in undefined behavior.
*/
uint32_t value_get_u32(const value_t *p_value);
uint32_t value_get_u32(const value_t *value);
/*!
* @brief Retrieves an unsigned 8-bit immediate value from a `value_t`.
*
* @pre The `p_value` must be of type `IR_TYPE_U8`.
* @param p_value Pointer to the `value_t` instance.
* @retval uint8_t The 8-bit unsigned immediate value stored in `p_value`.
* @pre The `value` must be of type `IR_TYPE_U8`.
* @param value Pointer to the `value_t` instance.
* @retval uint8_t The 8-bit unsigned immediate value stored in `value`.
* @warning Calling this function on a `value_t` not of type `IR_TYPE_U8`
* results in undefined behavior.
*/
uint8_t value_get_u8(const value_t *p_value);
uint8_t value_get_u8(const value_t *value);
/**
/*!
* @brief Retrieves an unsigned 1-bit immediate value from a `value_t`.
*
* @pre The `p_value` must be of type `IR_TYPE_U1`.
* @param p_value Pointer to the `value_t` instance.
* @retval bool The 1-bit unsigned immediate value stored in `p_value`.
* @pre The `value` must be of type `IR_TYPE_U1`.
* @param value Pointer to the `value_t` instance.
* @retval bool The 1-bit unsigned immediate value stored in `value`.
* @warning Calling this function on a `value_t` not of type `IR_TYPE_U1`
* results in undefined behavior.
*/
bool value_get_u1(const value_t *p_value);
bool value_get_u1(const value_t *value);
/**
/*!
* @brief Retrieves an A32 register identifier from a `value_t`.
*
* @pre The `p_value` must be of type `IR_TYPE_A32_REGISTER`.
* @param p_value Pointer to the `value_t` instance.
* @pre The `value` must be of type `IR_TYPE_A32_REGISTER`.
* @param value Pointer to the `value_t` instance.
* @retval pound::jit::a32_register_t The A32 register identifier stored in
* `p_value`.
* `value`.
* @warning Calling this function on a `value_t` not of type
* `IR_TYPE_A32_REGISTER` results in undefined behavior.
*/
pound::jit::a32_register_t value_get_a32_register(const value_t *p_value);
pound::jit::a32_register_t value_get_a32_register(const value_t *value);
} // namespace pound:::jit::ir
#endif // POUND_JIT_IR_TYPE_H