mirror of
https://github.com/pound-emu/pound.git
synced 2025-12-13 04:36:57 +00:00
jit/ir: Implement IR instruction management
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>
This commit is contained in:
parent
ffea35bc8f
commit
bd0bf1deba
8 changed files with 375 additions and 28 deletions
|
|
@ -111,7 +111,7 @@ add_subdirectory(src/targets/switch1/hardware)
|
|||
include(TestBigEndian)
|
||||
TEST_BIG_ENDIAN(WORDS_BIGENDIAN)
|
||||
|
||||
list(APPEND POUND_PROJECT_TARGETS common host pvm)
|
||||
list(APPEND POUND_PROJECT_TARGETS common host pvm jit)
|
||||
foreach(TARGET ${POUND_PROJECT_TARGETS})
|
||||
# Apply Endianness definitions to all our targets.
|
||||
if(WORDS_BIGENDIAN)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ target_sources(jit PRIVATE
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/ir/type.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ir/value.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ir/opcode.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ir/instruction.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(jit PRIVATE common host)
|
||||
|
|
|
|||
163
src/jit/ir/instruction.cpp
Normal file
163
src/jit/ir/instruction.cpp
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
#include "instruction.h"
|
||||
#include "common/passert.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#define LOG_MODULE "jit"
|
||||
#include "common/logging.h"
|
||||
|
||||
namespace pound::jit::ir {
|
||||
|
||||
const value_t*
|
||||
instruction_get_arg (const instruction_t *instruction, const size_t arg_index)
|
||||
{
|
||||
PVM_ASSERT(nullptr != instruction);
|
||||
PVM_ASSERT(arg_index < MAX_IR_ARGS);
|
||||
|
||||
const value_t *arg = &instruction->args[arg_index];
|
||||
PVM_ASSERT(nullptr != arg);
|
||||
return arg;
|
||||
}
|
||||
|
||||
const uint64_t
|
||||
instruction_get_arg_u64(const instruction_t *instruction, const size_t arg_index)
|
||||
{
|
||||
PVM_ASSERT(nullptr != instruction);
|
||||
PVM_ASSERT(arg_index < MAX_IR_ARGS);
|
||||
|
||||
const value_t* arg = instruction_get_arg(instruction, arg_index);
|
||||
PVM_ASSERT(nullptr != arg);
|
||||
|
||||
PVM_ASSERT(IR_TYPE_U64 == arg->type);
|
||||
const uint64_t value = value_get_u64(arg);
|
||||
return value;
|
||||
}
|
||||
|
||||
const uint32_t
|
||||
instruction_get_arg_u32(const instruction_t *instruction, const size_t arg_index)
|
||||
{
|
||||
PVM_ASSERT(nullptr != instruction);
|
||||
PVM_ASSERT(arg_index < MAX_IR_ARGS);
|
||||
|
||||
const value_t* arg = instruction_get_arg(instruction, arg_index);
|
||||
PVM_ASSERT(nullptr != arg);
|
||||
|
||||
PVM_ASSERT(IR_TYPE_U32 == arg->type);
|
||||
const uint32_t value = value_get_u32(arg);
|
||||
return value;
|
||||
}
|
||||
|
||||
const uint8_t
|
||||
instruction_get_arg_u8(const instruction_t *instruction, const size_t arg_index)
|
||||
{
|
||||
PVM_ASSERT(nullptr != instruction);
|
||||
PVM_ASSERT(arg_index < MAX_IR_ARGS);
|
||||
|
||||
const value_t* arg = instruction_get_arg(instruction, arg_index);
|
||||
PVM_ASSERT(nullptr != arg);
|
||||
|
||||
PVM_ASSERT(IR_TYPE_U8 == arg->type);
|
||||
const uint8_t value = value_get_u8(arg);
|
||||
return value;
|
||||
}
|
||||
|
||||
const bool
|
||||
instruction_get_arg_u1(const instruction_t *instruction, const size_t arg_index)
|
||||
{
|
||||
PVM_ASSERT(nullptr != instruction);
|
||||
PVM_ASSERT(arg_index < MAX_IR_ARGS);
|
||||
|
||||
const value_t* arg = instruction_get_arg(instruction, arg_index);
|
||||
PVM_ASSERT(nullptr != arg);
|
||||
|
||||
PVM_ASSERT(IR_TYPE_U1 == arg->type);
|
||||
const uint8_t value = value_get_u1(arg);
|
||||
return value;
|
||||
}
|
||||
|
||||
const pound::jit::a32_register_t
|
||||
instruction_get_arg_a32_register(const instruction_t *instruction, const size_t arg_index)
|
||||
{
|
||||
PVM_ASSERT(nullptr != instruction);
|
||||
PVM_ASSERT(arg_index < MAX_IR_ARGS);
|
||||
|
||||
const value_t* arg = instruction_get_arg(instruction, arg_index);
|
||||
PVM_ASSERT(nullptr != arg);
|
||||
|
||||
PVM_ASSERT(IR_TYPE_A32_REGISTER == arg->type);
|
||||
const pound::jit::a32_register_t value = value_get_a32_register(arg);
|
||||
return value;
|
||||
}
|
||||
|
||||
const type_t
|
||||
instruction_get_return_type (const instruction_t *instruction)
|
||||
{
|
||||
PVM_ASSERT(nullptr != instruction);
|
||||
PVM_ASSERT(instruction->opcode < NUM_OPCODE);
|
||||
|
||||
const decoded_opcode_t *decoded_opcode = &g_opcodes[instruction->opcode];
|
||||
PVM_ASSERT(nullptr != decoded_opcode);
|
||||
|
||||
return decoded_opcode->type;
|
||||
}
|
||||
|
||||
const char*
|
||||
instruction_get_opcode_name(const instruction_t *instruction)
|
||||
{
|
||||
PVM_ASSERT(nullptr != instruction);
|
||||
|
||||
const decoded_opcode_t *decoded_opcode = &g_opcodes[instruction->opcode];
|
||||
PVM_ASSERT(nullptr != decoded_opcode);
|
||||
|
||||
const char *name = decoded_opcode->name;
|
||||
PVM_ASSERT(nullptr != name);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
175
src/jit/ir/instruction.h
Normal file
175
src/jit/ir/instruction.h
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
#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
|
||||
|
|
@ -7,6 +7,8 @@
|
|||
* by including "opcode.inc", which is processed using X-macros.
|
||||
*/
|
||||
|
||||
#ifndef POUMD_JIT_IR_OPCODE_H
|
||||
#define POUMD_JIT_IR_OPCODE_H
|
||||
#include "type.h"
|
||||
|
||||
namespace pound::jit::ir {
|
||||
|
|
@ -56,3 +58,4 @@ extern decoded_opcode_t g_opcodes[NUM_OPCODE];
|
|||
|
||||
void opcode_init(void);
|
||||
}
|
||||
#endif // POUMD_JIT_IR_OPCODE_H
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
* This header declares the `type_t ` enumeration, which forms the basis of
|
||||
* type identification and checking within the JIT's IR.
|
||||
*/
|
||||
|
||||
#ifndef POUND_JIT_IR_TYPE_H
|
||||
#define POUND_JIT_IR_TYPE_H
|
||||
namespace pound::jit::ir {
|
||||
|
||||
/*!
|
||||
|
|
@ -60,3 +61,4 @@ typedef enum
|
|||
*/
|
||||
bool are_types_compatible(const type_t t1, const type_t t2);
|
||||
} // namespace pound::jit::ir
|
||||
#endif // POUND_JIT_IR_TYPE_H
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ value_init (value_t *p_value)
|
|||
}
|
||||
|
||||
void
|
||||
value_init_from_u64 (value_t *p_value, uint64_t u64)
|
||||
value_init_from_u64 (value_t *p_value, const uint64_t u64)
|
||||
{
|
||||
PVM_ASSERT(nullptr != p_value);
|
||||
p_value->type = IR_TYPE_U64;
|
||||
|
|
@ -25,7 +25,7 @@ value_init_from_u64 (value_t *p_value, uint64_t u64)
|
|||
}
|
||||
|
||||
void
|
||||
value_init_from_u32 (value_t *p_value, uint32_t u32)
|
||||
value_init_from_u32 (value_t *p_value, const uint32_t u32)
|
||||
{
|
||||
PVM_ASSERT(nullptr != p_value);
|
||||
p_value->type = IR_TYPE_U32;
|
||||
|
|
@ -33,7 +33,7 @@ value_init_from_u32 (value_t *p_value, uint32_t u32)
|
|||
}
|
||||
|
||||
void
|
||||
value_init_from_u8 (value_t *p_value, uint8_t u8)
|
||||
value_init_from_u8 (value_t *p_value, const uint8_t u8)
|
||||
{
|
||||
PVM_ASSERT(nullptr != p_value);
|
||||
p_value->type = IR_TYPE_U8;
|
||||
|
|
@ -41,7 +41,7 @@ value_init_from_u8 (value_t *p_value, uint8_t u8)
|
|||
}
|
||||
|
||||
void
|
||||
value_init_from_u1 (value_t *p_value, bool u1)
|
||||
value_init_from_u1 (value_t *p_value, const bool u1)
|
||||
{
|
||||
PVM_ASSERT(nullptr != p_value);
|
||||
p_value->type = IR_TYPE_U1;
|
||||
|
|
@ -49,7 +49,7 @@ value_init_from_u1 (value_t *p_value, bool u1)
|
|||
}
|
||||
|
||||
void
|
||||
value_init_from_a32_register (value_t *p_value, a32_register_t reg)
|
||||
value_init_from_a32_register (value_t *p_value, const a32_register_t reg)
|
||||
{
|
||||
PVM_ASSERT(nullptr != p_value);
|
||||
p_value->type = IR_TYPE_A32_REGISTER;
|
||||
|
|
@ -62,36 +62,36 @@ value_init_from_a32_register (value_t *p_value, a32_register_t reg)
|
|||
* ============================================================================
|
||||
*/
|
||||
|
||||
uint64_t
|
||||
value_get_u64 (value_t *p_value)
|
||||
const uint64_t
|
||||
value_get_u64 (const value_t *p_value)
|
||||
{
|
||||
PVM_ASSERT(IR_TYPE_U64 == p_value->type);
|
||||
return p_value->inner.immediate_u64;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
value_get_u32 (value_t *p_value)
|
||||
const uint32_t
|
||||
value_get_u32 (const value_t *p_value)
|
||||
{
|
||||
PVM_ASSERT(IR_TYPE_U32 == p_value->type);
|
||||
return p_value->inner.immediate_u32;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
value_get_u8 (value_t *p_value)
|
||||
const uint8_t
|
||||
value_get_u8 (const value_t *p_value)
|
||||
{
|
||||
PVM_ASSERT(IR_TYPE_U8 == p_value->type);
|
||||
return p_value->inner.immediate_u8;
|
||||
}
|
||||
|
||||
bool
|
||||
value_get_u1 (value_t *p_value)
|
||||
const bool
|
||||
value_get_u1 (const value_t *p_value)
|
||||
{
|
||||
PVM_ASSERT(IR_TYPE_U1 == p_value->type);
|
||||
return p_value->inner.immediate_u1;
|
||||
}
|
||||
|
||||
pound::jit::a32_register_t
|
||||
value_get_a32_register (value_t *p_value)
|
||||
const pound::jit::a32_register_t
|
||||
value_get_a32_register (const value_t *p_value)
|
||||
{
|
||||
PVM_ASSERT(IR_TYPE_A32_REGISTER == p_value->type);
|
||||
return p_value->inner.immediate_a32_register;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
* approach to store different types of data safely.
|
||||
*/
|
||||
|
||||
#ifndef POUND_JIT_IR_VALUE_H
|
||||
#define POUND_JIT_IR_VALUE_H
|
||||
#include <stdint.h>
|
||||
#include "type.h"
|
||||
#include "jit/a32_types.h"
|
||||
|
|
@ -58,7 +60,7 @@ void value_init (value_t *p_value);
|
|||
* @post The `p_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 *p_value, const uint64_t u64);
|
||||
|
||||
/*!
|
||||
* @brief Initializes a `value_t` instance to hold an unsigned 32-bit immediate value.
|
||||
|
|
@ -68,7 +70,7 @@ void value_init_from_u64 (value_t *p_value, uint64_t u64);
|
|||
* @post The `p_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 *p_value, const uint32_t u32);
|
||||
|
||||
/*!
|
||||
* @brief Initializes a `value_t` instance to hold an unsigned 8-bit immediate value.
|
||||
|
|
@ -78,7 +80,7 @@ void value_init_from_u32 (value_t *p_value, uint32_t u32);
|
|||
* @post The `p_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 *p_value, const uint8_t u8);
|
||||
|
||||
/*!
|
||||
* @brief Initializes a `value_t` instance to hold a 1-bit boolean immediate value.
|
||||
|
|
@ -88,7 +90,7 @@ void value_init_from_u8 (value_t *p_value, uint8_t u8);
|
|||
* @post The `p_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 *p_value, const bool u1);
|
||||
|
||||
/*!
|
||||
* @brief Initializes a `value_t` instance to hold an A32 register identifier.
|
||||
|
|
@ -101,7 +103,7 @@ void value_init_from_u1 (value_t *p_value, bool u1);
|
|||
* @post The `p_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 *p_value, const a32_register_t reg);
|
||||
|
||||
/*!
|
||||
* @brief Retrieves an unsigned 64-bit immediate value from a `value_t`.
|
||||
|
|
@ -112,7 +114,7 @@ void value_init_from_a32_register (value_t *p_value, a32_register_t reg);
|
|||
* @warning Calling this function on a `value_t` not of type `IR_TYPE_U64`
|
||||
* results in undefined behavior.
|
||||
*/
|
||||
uint64_t value_get_u64 (value_t *p_value);
|
||||
const uint64_t value_get_u64 (const value_t *p_value);
|
||||
|
||||
|
||||
/*!
|
||||
|
|
@ -124,7 +126,7 @@ uint64_t value_get_u64 (value_t *p_value);
|
|||
* @warning Calling this function on a `value_t` not of type `IR_TYPE_U32`
|
||||
* results in undefined behavior.
|
||||
*/
|
||||
uint32_t value_get_u32 (value_t *p_value);
|
||||
const uint32_t value_get_u32 (const value_t *p_value);
|
||||
|
||||
/*!
|
||||
* @brief Retrieves an unsigned 8-bit immediate value from a `value_t`.
|
||||
|
|
@ -135,7 +137,7 @@ uint32_t value_get_u32 (value_t *p_value);
|
|||
* @warning Calling this function on a `value_t` not of type `IR_TYPE_U8`
|
||||
* results in undefined behavior.
|
||||
*/
|
||||
uint8_t value_get_u8 (value_t *p_value);
|
||||
const uint8_t value_get_u8 (const value_t *p_value);
|
||||
|
||||
/**
|
||||
* @brief Retrieves an unsigned 1-bit immediate value from a `value_t`.
|
||||
|
|
@ -146,7 +148,7 @@ uint8_t value_get_u8 (value_t *p_value);
|
|||
* @warning Calling this function on a `value_t` not of type `IR_TYPE_U1`
|
||||
* results in undefined behavior.
|
||||
*/
|
||||
bool value_get_u1 (value_t *p_value);
|
||||
const bool value_get_u1 (const value_t *p_value);
|
||||
|
||||
/**
|
||||
* @brief Retrieves an A32 register identifier from a `value_t`.
|
||||
|
|
@ -157,5 +159,6 @@ bool value_get_u1 (value_t *p_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 (value_t *p_value);
|
||||
const pound::jit::a32_register_t value_get_a32_register (const value_t *p_value);
|
||||
} // namespace pound:::jit::ir
|
||||
#endif // POUND_JIT_IR_TYPE_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue