mirror of
https://github.com/pound-emu/ballistic.git
synced 2026-01-31 01:15:21 +01:00
63 lines
2.0 KiB
C
63 lines
2.0 KiB
C
#include "bal_ir_emitter.h"
|
|
#include <stdbool.h>
|
|
|
|
#define BAL_OPCODE_SHIFT_POSITION 53U
|
|
#define BAL_SOURCE1_SHIFT_POSITION 35U
|
|
#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 ***/
|