mirror of
https://github.com/pound-emu/pound.git
synced 2025-12-11 07:36:57 +00:00
Compare commits
2 commits
21c0f0bdef
...
0011bb7825
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0011bb7825 | ||
|
|
d61fbe3514 |
4 changed files with 78 additions and 174 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue