mirror of
https://github.com/pound-emu/ballistic.git
synced 2026-01-31 01:15:21 +01:00
engine: intern constants
This does two things so I'll split them. (1) Add function intern_constant() which adds a constant to the constants array and returns the index. The assembly for this function is beautiful. Only one load and store on a successfull path. Dump of assembler code for function intern_constant: 0x0000000000010ee0 <+0>: ldr w8, [x4] 0x0000000000010ee4 <+4>: cbnz w8, 0x10f08 <intern_constant+40> 0x0000000000010ee8 <+8>: ldrh w8, [x2] 0x0000000000010eec <+12>: cmp x3, x8 0x0000000000010ef0 <+16>: b.ls 0x10f10 <intern_constant+48> // b.plast 0x0000000000010ef4 <+20>: str w0, [x1, x8, lsl #2] 0x0000000000010ef8 <+24>: add w9, w8, #0x1 0x0000000000010efc <+28>: orr w0, w8, #0x10000 0x0000000000010f00 <+32>: strh w9, [x2] 0x0000000000010f04 <+36>: ret 0x0000000000010f08 <+40>: mov w0, #0x10000 // #65536 0x0000000000010f0c <+44>: ret 0x0000000000010f10 <+48>: mov w8, #0xffffff9c // #-100 0x0000000000010f14 <+52>: mov w0, #0x10000 // #65536 0x0000000000010f18 <+56>: str w8, [x4] 0x0000000000010f1c <+60>: ret End of assembler dump. (2) I've decided that the entire translation code will fit in bal_engine.c so the bal_ir_immiter and bal_translator files are not needed anymore. I moved their preprocessor definitions into bal_engine.c Signed-off-by: Ronald Caesar <github43132@proton.me>
This commit is contained in:
@@ -36,7 +36,6 @@ add_library(Ballistic STATIC
|
||||
src/decoder.c
|
||||
src/decoder_table_gen.c
|
||||
src/bal_engine.c
|
||||
src/bal_translator.c
|
||||
src/bal_memory.c
|
||||
)
|
||||
|
||||
|
||||
@@ -132,7 +132,6 @@ BAL_HOT bal_error_t bal_engine_reset(bal_engine_t *engine);
|
||||
/// caller may have allocated it on the stack.
|
||||
BAL_COLD void bal_engine_destroy(bal_allocator_t *allocator,
|
||||
bal_engine_t *engine);
|
||||
|
||||
#endif /* BALLISTIC_ENGINE_H */
|
||||
|
||||
/*** end of file ***/
|
||||
|
||||
@@ -9,8 +9,21 @@
|
||||
//
|
||||
#define MAX_GUEST_REGISTERS 128
|
||||
|
||||
// Helper macro to align `x` UP to the nearest memory alignment.
|
||||
//
|
||||
#define BAL_OPCODE_SHIFT_POSITION 51U
|
||||
#define BAL_SOURCE1_SHIFT_POSITION 34U
|
||||
#define BAL_SOURCE2_SHIFT_POSITION 17U
|
||||
|
||||
/// The maximum value for an Opcode.
|
||||
#define BAL_OPCODE_SIZE (1U << 11U)
|
||||
|
||||
/// The maximum value for an Operand Index.
|
||||
/// Bit 17 is reserved for the "Is Constant" flag.
|
||||
#define BAL_SOURCE_SIZE (1U << 16U)
|
||||
|
||||
/// The bit position for the is constant flag in a bal_instruction_t.
|
||||
#define BAL_IS_CONSTANT_BIT_POSITION (1U << 16U)
|
||||
|
||||
/// Helper macro to align `x` UP to the nearest memory alignment.
|
||||
#define BAL_ALIGN_UP(x, memory_alignment) \
|
||||
(((x) + ((memory_alignment) - 1)) & ~((memory_alignment) - 1))
|
||||
|
||||
@@ -94,8 +107,6 @@ bal_engine_translate (bal_engine_t *BAL_RESTRICT engine,
|
||||
return BAL_ERROR_ENGINE_STATE_INVALID;
|
||||
}
|
||||
|
||||
// Load state to registers.
|
||||
//
|
||||
bal_instruction_t *BAL_RESTRICT ir_instruction_cursor
|
||||
= engine->instructions + engine->instruction_count;
|
||||
|
||||
@@ -168,3 +179,27 @@ extract_operand_value (bal_instruction_t instruction,
|
||||
uint32_t bits = (instruction >> (uint32_t)operand->bit_position) & mask;
|
||||
return bits;
|
||||
}
|
||||
|
||||
BAL_HOT static uint32_t
|
||||
intern_constant (bal_constant_t constant,
|
||||
bal_constant_t *BAL_RESTRICT constants,
|
||||
bal_constant_count_t *BAL_RESTRICT count,
|
||||
size_t constants_max_size,
|
||||
bal_error_t *BAL_RESTRICT status)
|
||||
{
|
||||
if (BAL_UNLIKELY(*status != BAL_SUCCESS))
|
||||
{
|
||||
return 0 | BAL_IS_CONSTANT_BIT_POSITION;
|
||||
}
|
||||
|
||||
if (BAL_UNLIKELY(*count >= constants_max_size))
|
||||
{
|
||||
*status = BAL_ERROR_INSTRUCTION_OVERFLOW;
|
||||
return 0 | BAL_IS_CONSTANT_BIT_POSITION;
|
||||
}
|
||||
|
||||
constants[*count] = constant;
|
||||
uint32_t index = *count | BAL_IS_CONSTANT_BIT_POSITION;
|
||||
(*count)++;
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
#include "bal_ir_emitter.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#define BAL_OPCODE_SHIFT_POSITION 51U
|
||||
#define BAL_SOURCE1_SHIFT_POSITION 34U
|
||||
#define BAL_SOURCE2_SHIFT_POSITION 17U
|
||||
|
||||
#define BAL_IS_CONSTANT_BIT_POSITION (1U << 16U)
|
||||
|
||||
bal_error_t
|
||||
emit_instruction (bal_engine_t *engine,
|
||||
uint32_t opcode,
|
||||
uint32_t source1,
|
||||
uint32_t source2,
|
||||
uint32_t source3,
|
||||
bal_bit_width_t bit_width)
|
||||
{
|
||||
// This is a hot function, no argument error handling. Segfault if the user
|
||||
// passes NULL.
|
||||
|
||||
if (BAL_UNLIKELY(engine->status != BAL_SUCCESS))
|
||||
{
|
||||
return BAL_ERROR_ENGINE_STATE_INVALID;
|
||||
}
|
||||
|
||||
bool is_greater_than_instructions_array
|
||||
= (engine->instruction_count >= engine->instructions_size);
|
||||
|
||||
bool is_greater_than_source_size
|
||||
= (engine->instruction_count >= (BAL_SOURCE_SIZE - 1));
|
||||
|
||||
if (BAL_UNLIKELY((true == is_greater_than_instructions_array)
|
||||
|| (true == is_greater_than_source_size)))
|
||||
{
|
||||
engine->status = BAL_ERROR_INSTRUCTION_OVERFLOW;
|
||||
return engine->status;
|
||||
}
|
||||
|
||||
bal_instruction_t opcode_bits = (BAL_OPCODE_SIZE - 1U) & opcode;
|
||||
bal_instruction_t source1_bits
|
||||
= ((BAL_SOURCE_SIZE - 1U) | BAL_IS_CONSTANT_BIT_POSITION) & source1;
|
||||
|
||||
bal_instruction_t source2_bits
|
||||
= ((BAL_SOURCE_SIZE - 1U) | BAL_IS_CONSTANT_BIT_POSITION) & source2;
|
||||
|
||||
bal_instruction_t source3_bits
|
||||
= ((BAL_SOURCE_SIZE - 1U) | BAL_IS_CONSTANT_BIT_POSITION) & source3;
|
||||
|
||||
bal_instruction_t instruction
|
||||
= (opcode_bits << BAL_OPCODE_SHIFT_POSITION)
|
||||
| (source1_bits << BAL_SOURCE1_SHIFT_POSITION)
|
||||
| (source2_bits << BAL_SOURCE2_SHIFT_POSITION) | source3_bits;
|
||||
|
||||
engine->instructions[engine->instruction_count] = instruction;
|
||||
engine->ssa_bit_widths[engine->instruction_count] = bit_width;
|
||||
engine->status = BAL_SUCCESS;
|
||||
++engine->instruction_count;
|
||||
|
||||
return engine->status;
|
||||
}
|
||||
|
||||
/*** end of file ***/
|
||||
@@ -1,51 +0,0 @@
|
||||
/** @file bal_ir_emitter.h
|
||||
*
|
||||
* @brief Responsible for encoding the IR into the memory arena.
|
||||
*/
|
||||
|
||||
#ifndef BALLISTIC_IR_EMITTER_H
|
||||
#define BALLISTIC_IR_EMITTER_H
|
||||
|
||||
#include "bal_attributes.h"
|
||||
#include "bal_types.h"
|
||||
#include "bal_errors.h"
|
||||
#include "bal_engine.h"
|
||||
|
||||
/*!
|
||||
* @brief The maximum value for an Opcode.
|
||||
*/
|
||||
#define BAL_OPCODE_SIZE (1U << 11U)
|
||||
|
||||
/*!
|
||||
* @brief The maximum value for an Operand Index.
|
||||
* @note Bit 17 is reserved for the "Is Constant" flag.
|
||||
*/
|
||||
#define BAL_SOURCE_SIZE (1U << 16U)
|
||||
|
||||
/*!
|
||||
* @brief Appends a new instruction to the linear instruction stream.
|
||||
*
|
||||
* @param[in,out] engine The JIT engine containing the instruction buffer.
|
||||
* @param[in] opcode The operation to perform (see @ref bal_opcode_t).
|
||||
* @param[in] source1 SSA ID or Constant Pool Index for operand 1.
|
||||
* @param[in] source2 SSA ID or Constant Pool Index for operand 2.
|
||||
* @param[in] source3 SSA ID or Constant Pool Index for operand 3.
|
||||
* @param[in] bit_width The bit width of the variable defined by this
|
||||
* instruction.
|
||||
*
|
||||
* @note Increments engine->instruction_count when called.
|
||||
*
|
||||
* @return BAL_SUCCESS on success.
|
||||
* @return BAL_ERROR_INSTRUCTION_OVERFLOW if the block limit is reached.
|
||||
* @return BAL_ERROR_ENGINE_STATE_INVALID if engine->status != BAL_SUCCESS.
|
||||
*/
|
||||
BAL_HOT bal_error_t emit_instruction(bal_engine_t *engine,
|
||||
uint32_t opcode,
|
||||
uint32_t source1,
|
||||
uint32_t source2,
|
||||
uint32_t source3,
|
||||
bal_bit_width_t bit_width);
|
||||
|
||||
#endif /* BALLISTIC_IR_EMITTER_H */
|
||||
|
||||
/*** end of file ***/
|
||||
@@ -1,3 +0,0 @@
|
||||
#include "bal_translator.h"
|
||||
|
||||
/*** end of file ***/
|
||||
@@ -1,25 +0,0 @@
|
||||
/** @file bal_translator.h
|
||||
*
|
||||
* @brief ARM to Ballistic IR Translation Interface.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* This module represents the frontend of Ballistic. It performas the following
|
||||
* in a single pass:
|
||||
*
|
||||
* 1. Fetch
|
||||
* 2. Decode
|
||||
* 3. SSA Construction
|
||||
*/
|
||||
|
||||
#ifndef BAL_TRANSLATOR_H
|
||||
#define BAL_TRANSLATOR_H
|
||||
|
||||
#include "bal_engine.h"
|
||||
#include "bal_types.h"
|
||||
#include "bal_errors.h"
|
||||
|
||||
|
||||
#endif /* BAL_TRANSLATOR_H */
|
||||
|
||||
/*** end of file ***/
|
||||
Reference in New Issue
Block a user