diff --git a/CMakeLists.txt b/CMakeLists.txt index a4d5d56..23e6c40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,8 +101,8 @@ add_subdirectory(3rd_Party) add_subdirectory(src/common) add_subdirectory(src/host) add_subdirectory(src/jit) -add_subdirectory(src/pvm) -add_subdirectory(src/targets/switch1/hardware) +#add_subdirectory(src/pvm) +#add_subdirectory(src/targets/switch1/hardware) #-------------------------------- # ---- Target Configurations ---- @@ -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 jit) +list(APPEND POUND_PROJECT_TARGETS common host jit) foreach(TARGET ${POUND_PROJECT_TARGETS}) # Apply Endianness definitions to all our targets. if(WORDS_BIGENDIAN) @@ -123,6 +123,7 @@ foreach(TARGET ${POUND_PROJECT_TARGETS}) $<$: -Wall -Wpedantic + -Wextra -Wshadow -Wpointer-arith -Wcast-qual @@ -152,11 +153,11 @@ target_link_libraries(Pound PRIVATE common host jit - pvm + #pvm - OpenGL::GL - SDL3::SDL3 - imgui + #OpenGL::GL + #SDL3::SDL3 + #imgui ) set(TEST_SRC diff --git a/src/jit/ir/instruction.cpp b/src/jit/ir/instruction.cpp index a65bc79..dd72e57 100644 --- a/src/jit/ir/instruction.cpp +++ b/src/jit/ir/instruction.cpp @@ -6,106 +6,105 @@ #include "common/logging.h" namespace pound::jit::ir { - -const value_t* -instruction_get_arg (const instruction_t *instruction, const size_t arg_index) +value_t * +instruction_get_arg (instruction_t *instruction, size_t arg_index) { PVM_ASSERT(nullptr != instruction); PVM_ASSERT(arg_index < MAX_IR_ARGS); - const value_t *arg = &instruction->args[arg_index]; + 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) +uint64_t +instruction_get_arg_u64 (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); + 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); + 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) +uint32_t +instruction_get_arg_u32 (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); + 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); + 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) +uint8_t +instruction_get_arg_u8 (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); + 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); + uint8_t value = value_get_u8(arg); return value; } -const bool -instruction_get_arg_u1(const instruction_t *instruction, const size_t arg_index) +bool +instruction_get_arg_u1 (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); + 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); + 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) +pound::jit::a32_register_t +instruction_get_arg_a32_register (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); + 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); + pound::jit::a32_register_t value = value_get_a32_register(arg); return value; } -const type_t -instruction_get_return_type (const instruction_t *instruction) +type_t +instruction_get_return_type (instruction_t *instruction) { PVM_ASSERT(nullptr != instruction); PVM_ASSERT(instruction->opcode < NUM_OPCODE); - const decoded_opcode_t *decoded_opcode = &g_opcodes[instruction->opcode]; + 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) +const char * +instruction_get_opcode_name (const instruction_t *instruction) { PVM_ASSERT(nullptr != instruction); - const decoded_opcode_t *decoded_opcode = &g_opcodes[instruction->opcode]; + decoded_opcode_t *decoded_opcode = &g_opcodes[instruction->opcode]; PVM_ASSERT(nullptr != decoded_opcode); const char *name = decoded_opcode->name; diff --git a/src/jit/ir/instruction.h b/src/jit/ir/instruction.h index 8b43770..0832947 100644 --- a/src/jit/ir/instruction.h +++ b/src/jit/ir/instruction.h @@ -21,12 +21,12 @@ typedef struct instruction_t opcode_t opcode; // An array of arguments for this instruction. - value_t args[MAX_IR_ARGS]; + 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. + // Pointer to the previous instruction the intrusive list. struct instruction_t *previous; } instruction_t; @@ -34,8 +34,8 @@ typedef struct 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 - */ + * composed of `instruction_t` nodes. It is used to store sequences + */ typedef struct { // Pointer to the first instruction in the list. @@ -55,7 +55,7 @@ typedef struct * @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); +value_t *instruction_get_arg(instruction_t *instruction, size_t arg_index); /*! * Retrieves a U64 argument from an instruction. @@ -68,7 +68,7 @@ const value_t* instruction_get_arg (const instruction_t *instruction, const size * @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); +uint64_t instruction_get_arg_u64(instruction_t *instruction, size_t arg_index); /*! * @brief Retrieves a U32 argument from an instruction. @@ -81,7 +81,7 @@ const uint64_t instruction_get_arg_u64(const instruction_t *instruction, const s * @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); +uint32_t instruction_get_arg_u32(instruction_t *instruction, size_t arg_index); /*! * Retrives a U8 argument from an instruction. @@ -94,7 +94,7 @@ const uint32_t instruction_get_arg_u32(const instruction_t *instruction, const s * @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); +uint8_t instruction_get_arg_u8(instruction_t *instruction, size_t arg_index); /*! * @brief Retrieves a U1 (boolean) argument from an instruction. @@ -107,7 +107,7 @@ const uint8_t instruction_get_arg_u8(const instruction_t *instruction, const siz * @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); +bool instruction_get_arg_u1(instruction_t *instruction, size_t arg_index); /*! * @brief Retrieves an A32 register identifier argument from an instruction. @@ -120,7 +120,8 @@ const bool instruction_get_arg_u1(const instruction_t *instruction, const size_t * @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); +pound::jit::a32_register_t instruction_get_arg_a32_register( + instruction_t *instruction, size_t arg_index); /*! * @brief Gets the return type of an instruction based on its opcode. @@ -129,10 +130,10 @@ const pound::jit::a32_register_t instruction_get_arg_a32_register(const instruct * * @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`). + * @pre `instruction->opcode` must be a valid opcode index (less than + * `NUM_OPCODE`). */ -const type_t instruction_get_return_type (const instruction_t *instruction); - +type_t instruction_get_return_type(instruction_t *instruction); /*! * @brief Gets the name of an instruction's opcode as a C-string. @@ -141,10 +142,11 @@ const type_t instruction_get_return_type (const instruction_t *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 `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); +const char *instruction_get_opcode_name(instruction_t *instruction); /*! * @brief Appends an instruction to the tail of an instruction list. @@ -158,7 +160,8 @@ const char* instruction_get_opcode_name(const instruction_t *instruction); * @pre `list` must not be NULL. * @pre `instruction` must not be NULL. */ -void instruction_list_append (instruction_list_t *list, instruction_t *instruction); +void instruction_list_append(instruction_list_t *list, + instruction_t *instruction); /*! * @brief Removes an instruction from an instruction list. @@ -170,6 +173,7 @@ void instruction_list_append (instruction_list_t *list, instruction_t *instructi * @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); +void instruction_list_remove(instruction_list_t *list, + instruction_t *instruction); } #endif // POUND_JIT_IR_INSTRUCTION_H diff --git a/src/jit/ir/type.h b/src/jit/ir/type.h index d60f150..1d1f6b2 100644 --- a/src/jit/ir/type.h +++ b/src/jit/ir/type.h @@ -19,17 +19,18 @@ namespace pound::jit::ir { */ typedef enum { - IR_TYPE_VOID = 0, - IR_TYPE_U1 = 1 << 0, - IR_TYPE_U8 = 1 << 1, - IR_TYPE_U16 = 1 << 2, - IR_TYPE_U32 = 1 << 3, - IR_TYPE_U64 = 1 << 4, - IR_TYPE_U128 = 1 << 5, - IR_TYPE_A32_REGISTER = 1 << 6, // ARM32 GPR R0-R14 - IR_TYPE_A32_EXTENDED_REGISTER = 1 << 7, // ARM32 Extended Registers (e.g., for - IR_TYPE_CONDITION = 1 << 9, // Condition codes - IR_TYPE_MEMORY_ACCESS = 1 << 10, // Memory access type + IR_TYPE_VOID = 0, + IR_TYPE_U1 = 1 << 0, + IR_TYPE_U8 = 1 << 1, + IR_TYPE_U16 = 1 << 2, + IR_TYPE_U32 = 1 << 3, + IR_TYPE_U64 = 1 << 4, + IR_TYPE_U128 = 1 << 5, + IR_TYPE_A32_REGISTER = 1 << 6, // ARM32 GPR R0-R14 + IR_TYPE_A32_EXTENDED_REGISTER = 1 + << 7, // ARM32 Extended Registers (e.g., for + IR_TYPE_CONDITION = 1 << 9, // Condition codes + IR_TYPE_MEMORY_ACCESS = 1 << 10, // Memory access type #if 0 // VFP/NEON, or just R15 if treated specially) IR_TYPE_A32_CPSR = 1 << 8, // ARM32 CPSR/SPSR diff --git a/src/jit/ir/value.cpp b/src/jit/ir/value.cpp index f34e20a..cd40e35 100644 --- a/src/jit/ir/value.cpp +++ b/src/jit/ir/value.cpp @@ -52,7 +52,7 @@ void 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; + p_value->type = IR_TYPE_A32_REGISTER; p_value->inner.immediate_a32_register = reg; } @@ -62,35 +62,35 @@ value_init_from_a32_register (value_t *p_value, const a32_register_t reg) * ============================================================================ */ -const uint64_t +uint64_t value_get_u64 (const value_t *p_value) -{ +{ PVM_ASSERT(IR_TYPE_U64 == p_value->type); return p_value->inner.immediate_u64; } -const uint32_t +uint32_t value_get_u32 (const value_t *p_value) { PVM_ASSERT(IR_TYPE_U32 == p_value->type); return p_value->inner.immediate_u32; } -const uint8_t +uint8_t value_get_u8 (const value_t *p_value) { PVM_ASSERT(IR_TYPE_U8 == p_value->type); return p_value->inner.immediate_u8; } -const bool +bool value_get_u1 (const value_t *p_value) { PVM_ASSERT(IR_TYPE_U1 == p_value->type); return p_value->inner.immediate_u1; } -const pound::jit::a32_register_t +pound::jit::a32_register_t value_get_a32_register (const value_t *p_value) { PVM_ASSERT(IR_TYPE_A32_REGISTER == p_value->type); diff --git a/src/jit/ir/value.h b/src/jit/ir/value.h index ab69bb8..0a59e2a 100644 --- a/src/jit/ir/value.h +++ b/src/jit/ir/value.h @@ -19,7 +19,8 @@ namespace pound::jit::ir { /*! - * @brief A polymorphic container for values in the JIT's Intermediate Representation. + * @brief A polymorphic container for values in the JIT's Intermediate + * Representation. * * The `value_t` struct represents a single value within the IR. It can hold * various types of data, identified by the `type` member. The actual data @@ -50,47 +51,51 @@ typedef struct * 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 *p_value); /*! - * @brief Initializes a `value_t` instance to hold an unsigned 64-bit immediate 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 u64 The 64-bit unsigned immediate value to store. * @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, const uint64_t u64); +void value_init_from_u64(value_t *p_value, uint64_t u64); /*! - * @brief Initializes a `value_t` instance to hold an unsigned 32-bit immediate value. + * @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 u32 The 32-bit unsigned immediate value to store. * @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, const uint32_t u32); +void value_init_from_u32(value_t *p_value, uint32_t u32); /*! - * @brief Initializes a `value_t` instance to hold an unsigned 8-bit immediate value. + * @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 u8 The 8-bit unsigned immediate value to store. * @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, const uint8_t u8); +void value_init_from_u8(value_t *p_value, uint8_t u8); /*! - * @brief Initializes a `value_t` instance to hold a 1-bit boolean immediate value. + * @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 u1 The boolean (1-bit) immediate value to store. * @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, const bool u1); +void value_init_from_u1(value_t *p_value, bool u1); /*! * @brief Initializes a `value_t` instance to hold an A32 register identifier. @@ -103,7 +108,7 @@ void value_init_from_u1 (value_t *p_value, const 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, const a32_register_t reg); +void value_init_from_a32_register(value_t *p_value, a32_register_t reg); /*! * @brief Retrieves an unsigned 64-bit immediate value from a `value_t`. @@ -114,8 +119,7 @@ void value_init_from_a32_register (value_t *p_value, const a32_register_t reg); * @warning Calling this function on a `value_t` not of type `IR_TYPE_U64` * results in undefined behavior. */ -const uint64_t value_get_u64 (const value_t *p_value); - +uint64_t value_get_u64(const value_t *p_value); /*! * @brief Retrieves an unsigned 32-bit immediate value from a `value_t`. @@ -126,7 +130,7 @@ const uint64_t value_get_u64 (const value_t *p_value); * @warning Calling this function on a `value_t` not of type `IR_TYPE_U32` * results in undefined behavior. */ -const uint32_t value_get_u32 (const value_t *p_value); +uint32_t value_get_u32(const value_t *p_value); /*! * @brief Retrieves an unsigned 8-bit immediate value from a `value_t`. @@ -137,7 +141,7 @@ const uint32_t value_get_u32 (const value_t *p_value); * @warning Calling this function on a `value_t` not of type `IR_TYPE_U8` * results in undefined behavior. */ -const uint8_t value_get_u8 (const value_t *p_value); +uint8_t value_get_u8(const value_t *p_value); /** * @brief Retrieves an unsigned 1-bit immediate value from a `value_t`. @@ -148,17 +152,18 @@ const uint8_t value_get_u8 (const value_t *p_value); * @warning Calling this function on a `value_t` not of type `IR_TYPE_U1` * results in undefined behavior. */ -const bool value_get_u1 (const value_t *p_value); +bool value_get_u1(const value_t *p_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. - * @retval pound::jit::a32_register_t The A32 register identifier stored in `p_value`. - * @warning Calling this function on a `value_t` not of type `IR_TYPE_A32_REGISTER` - * results in undefined behavior. + * @retval pound::jit::a32_register_t The A32 register identifier stored in + * `p_value`. + * @warning Calling this function on a `value_t` not of type + * `IR_TYPE_A32_REGISTER` results in undefined behavior. */ -const 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 *p_value); } // namespace pound:::jit::ir #endif // POUND_JIT_IR_TYPE_H