#define BC_LOG 1 #define BC_ASSERTS 1 #if BC_LOG #define bc_log(...) log_info(__VA_ARGS__) #else #define bc_log(...) #endif // // Generated using code_generating_script.py // enum Operation: S32{ BC_END_OF_INSTRUCTIONS, BC_POP_STACK, BC_PUSH_STACK, BC_LOAD_CONSTANT, BC_LOAD_FROM_MEMORY64, BC_LOAD_FROM_MEMORY32, BC_LOAD_FROM_MEMORY16, BC_LOAD_FROM_MEMORY8, BC_STORE_TO_MEMORY64, BC_STORE_TO_MEMORY32, BC_STORE_TO_MEMORY16, BC_STORE_TO_MEMORY8, BC_ADD_S64, BC_SUB_S64, BC_DIV_S64, BC_MUL_S64, BC_MOD_S64, BC_SHR_S64, BC_SHL_S64, BC_BITAND_S64, BC_BITOR_S64, BC_BITXOR_S64, BC_BITNOT_S64, BC_EQ_S64, BC_NEQ_S64, BC_GT_S64, BC_LT_S64, BC_OR_S64, BC_GTE_S64, BC_LTE_S64, BC_ADD_U64, BC_SUB_U64, BC_DIV_U64, BC_MUL_U64, BC_MOD_U64, BC_SHR_U64, BC_SHL_U64, BC_BITAND_U64, BC_BITOR_U64, BC_BITXOR_U64, BC_BITNOT_U64, BC_EQ_U64, BC_NEQ_U64, BC_GT_U64, BC_LT_U64, BC_OR_U64, BC_GTE_U64, BC_LTE_U64, BC_ADD_F64, BC_SUB_F64, BC_DIV_F64, BC_MUL_F64, BC_EQ_F64, BC_NEQ_F64, BC_GT_F64, BC_LT_F64, BC_GTE_F64, BC_LTE_F64, }; const char *op_name[] = { "BC_END_OF_INSTRUCTIONS", "BC_POP_STACK", "BC_PUSH_STACK", "BC_LOAD_CONSTANT", "BC_LOAD_FROM_MEMORY64", "BC_LOAD_FROM_MEMORY32", "BC_LOAD_FROM_MEMORY16", "BC_LOAD_FROM_MEMORY8", "BC_STORE_TO_MEMORY64", "BC_STORE_TO_MEMORY32", "BC_STORE_TO_MEMORY16", "BC_STORE_TO_MEMORY8", "BC_ADD_S64", "BC_SUB_S64", "BC_DIV_S64", "BC_MUL_S64", "BC_MOD_S64", "BC_SHR_S64", "BC_SHL_S64", "BC_BITAND_S64", "BC_BITOR_S64", "BC_BITXOR_S64", "BC_BITNOT_S64", "BC_EQ_S64", "BC_NEQ_S64", "BC_GT_S64", "BC_LT_S64", "BC_OR_S64", "BC_GTE_S64", "BC_LTE_S64", "BC_ADD_U64", "BC_SUB_U64", "BC_DIV_U64", "BC_MUL_U64", "BC_MOD_U64", "BC_SHR_U64", "BC_SHL_U64", "BC_BITAND_U64", "BC_BITOR_U64", "BC_BITXOR_U64", "BC_BITNOT_U64", "BC_EQ_U64", "BC_NEQ_U64", "BC_GT_U64", "BC_LT_U64", "BC_OR_U64", "BC_GTE_U64", "BC_LTE_U64", "BC_ADD_F64", "BC_SUB_F64", "BC_DIV_F64", "BC_MUL_F64", "BC_EQ_F64", "BC_NEQ_F64", "BC_GT_F64", "BC_LT_F64", "BC_GTE_F64", "BC_LTE_F64", }; // // **End** of generated using code_generating_script.py // typedef S32 Register_Index; union Register{ F64 f64; S64 s64; U64 *pointer_u64; U64 u64; S64 *pointer_s64; F64 *pointer_f64; U64 *pointer64; U8 *pointer; }; struct Instruction{ Operation operation; S32 index_c; union{ struct{ S32 index_a; S32 index_b; }; Register constant; }; U32 di; // @debug_id U32 debug_type_flag; Token *debug_pos; }; // // Bytecode interpreter context // struct Bc{ U32 dis; // @debug_id U64 *stack_bottom; U64 *stack_pointer; U64 *stack_top; Instruction *instruction_pointer; // @todo Array can change location !!!!!! Register *registers; Register *register_end; Array all_registers; Array used_registers; Array free_registers; Arena memory; Arena instructions; Arena stack; // We reserve 4 gibs and allocate only 4 kibs to make sure we know when we // accidently overshoot the stack by 2 gigabytes woo yeee }; // // Allocating and releasing is for codegen ! // function Register_Index allocate_register(Bc *b){ Register_Index result = -1; if(b->free_registers.len == 0) result = b->all_registers.addi({}); else result = b->free_registers.pop(); b->used_registers.add(result); return result; } function void release_register(Bc *b, Register_Index reg){ B32 found = false; For(b->used_registers){ if(it == reg){ b->used_registers.unordered_remove(&it); found = true; break; } } assert_msg(found, "Trying to release register that is not used"); b->free_registers.add(reg); } function Bc create_bytecode_interp(){ Bc b = {}; b.all_registers = array_make(pctx->heap, 1024); b.free_registers = array_make(pctx->heap, 1024); b.used_registers = array_make(pctx->heap, 1024); { arena_init(&b.instructions, "Bytecode instructions"_s); arena_push_size(&b.instructions, 16); // Commit arena_clear(&b.instructions); } { arena_init(&b.stack, "Bytecode stack"_s); arena_push_size(&b.stack, kib(4)); // Setup a 4 kilobyte stack } arena_init(&b.memory, "Bytecode memory"_s); return b; } function void destroy_bytecode_interp(Bc *b){ arena_release(&b->instructions); arena_release(&b->stack); arena_release(&b->memory); } function Instruction * new_instruction(Bc *b, Token *pos){ Instruction *i = exp_alloc_type(&b->instructions, Instruction); i->di = b->dis++; i->debug_pos = pos; return i; } function void emit_load_constant_f64(Bc *b, Token *pos, Register_Index dst, F64 constant){ auto i = new_instruction(b, pos); i->operation = BC_LOAD_CONSTANT; i->constant.f64 = constant; i->index_c = dst; i->debug_type_flag = TYPE_F64; } function void emit_load_constant_s64(Bc *b, Token *pos, Register_Index dst, S64 constant){ auto i = new_instruction(b, pos); i->operation = BC_LOAD_CONSTANT; i->constant.s64 = constant; i->index_c = dst; i->debug_type_flag = TYPE_S64; } function void emit_load_constant_u64(Bc *b, Token *pos, Register_Index dst, U64 constant){ auto i = new_instruction(b, pos); i->operation = BC_LOAD_CONSTANT; i->constant.u64 = constant; i->index_c = dst; i->debug_type_flag = TYPE_U64; } function void emit_load_constant_address(Bc *b, Token *pos, Register_Index dst, void *address){ auto i = new_instruction(b, pos); i->operation = BC_LOAD_CONSTANT; i->constant.pointer = (U8 *)address; i->index_c = dst; i->debug_type_flag = TYPE_POINTER; } function void emit_push(Bc *b, Token *pos, Register_Index src){ auto i = new_instruction(b, pos); i->operation = BC_PUSH_STACK; i->index_a = src; } function void emit_pop(Bc *b, Token *pos, Register_Index dst){ auto i = new_instruction(b, pos); i->operation = BC_POP_STACK; i->index_c = dst; } function void emit_memory(Bc *b, Token *pos, Operation ins, Register_Index dst, Register_Index src){ auto i = new_instruction(b, pos); i->operation = ins; i->index_c = dst; i->index_a = src; } function void emit_arithmetic(Bc *b, Token *pos, Operation ins, Register_Index left, Register_Index right, Register_Index dst){ Instruction *i = new_instruction(b, pos); i->operation = ins; i->index_a = left; i->index_b = right; i->index_c = dst; } function void emit_end(Bc *b){ Instruction *i = new_instruction(b, 0); i->di = b->dis++; i->operation = BC_END_OF_INSTRUCTIONS; } function void run_bytecode_interp(Bc *b){ // Setup registers b->instruction_pointer = (Instruction *)b->instructions.memory.data; b->stack_pointer = b->stack_bottom = (U64 *)b->stack.memory.data; b->stack_top = (U64 *)(b->stack.memory.data + b->stack.len); b->registers = &b->all_registers[0]; b->register_end = b->all_registers.end(); for(;;){ Instruction *instr = b->instruction_pointer++; #if BC_ASSERTS print_token_line(instr->debug_pos); assert_msg(b->stack_pointer < b->stack_top, "Bytecode stack overflow"); assert_msg(b->stack_pointer >= b->stack_bottom, "Bytecode stack underflow"); assert_msg(b->registers < b->register_end, "Bytecode interpreter bug, register pointer is pointing over last possible register"); #endif bc_log("i%u[0x%llx] %s ", instr->di, instr, op_name[instr->operation]); switch(instr->operation){ invalid_default_case; case BC_LOAD_FROM_MEMORY64:{ U64 *load_address = b->registers[instr->index_a].pointer64; b->registers[instr->index_c].u64 = *load_address; bc_log("load_address[r%u, %llx] dst[r%u] [0x%llx|%lld|%f]", instr->index_a, load_address, instr->index_c, b->registers[instr->index_c].u64, b->registers[instr->index_c].u64, b->registers[instr->index_c].u64); }break; case BC_STORE_TO_MEMORY64:{ U64 *store_address = b->registers[instr->index_c].pointer64; *store_address = b->registers[instr->index_a].u64; bc_log("src[r%u] store_address[r%u, %llx] value_written[0x%llx|%lld|%f]", instr->index_a, instr->index_c, store_address, *store_address, *store_address, *store_address); }break; case BC_PUSH_STACK:{ U64 *stack = b->stack_pointer++; U64 src = b->registers[instr->index_a].u64; bc_log("r%u(src) [0x%llx|%lld|%f]", instr->index_a, src, src, src); *stack = src; }break; case BC_POP_STACK:{ U64 *stack = --b->stack_pointer; bc_log("r%u(dst) [0x%llx|%lld|%f]", instr->index_c, *stack, *stack, *stack); b->registers[instr->index_c].u64 = *stack; }break; case BC_END_OF_INSTRUCTIONS:{ goto end_of_program; }break; case BC_LOAD_CONSTANT: { b->registers[instr->index_c] = instr->constant; #if BC_LOG switch(instr->debug_type_flag){ case TYPE_S64: bc_log("dst[r%u] S64[%lld]", instr->index_c, instr->constant.s64); break; case TYPE_U64: bc_log("dst[r%u] U64[%llu]", instr->index_c, instr->constant.u64); break; case TYPE_F64: bc_log("dst[r%u] F64[%f]" , instr->index_c, instr->constant.f64); break; case TYPE_POINTER: bc_log("dst[r%u] Pointer[0x%llx]" , instr->index_c, instr->constant.pointer64); break; invalid_default_case; } #endif }break; // // Generated using code_generating_script.py // case BC_ADD_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left + right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] + [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_SUB_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left - right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] - [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_DIV_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left / right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] / [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_MUL_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left * right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] * [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_MOD_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left % right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] % [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_SHR_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left >> right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] >> [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_SHL_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left << right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] << [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_BITAND_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left & right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] & [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_BITOR_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left | right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] | [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_BITXOR_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left ^ right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] ^ [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_BITNOT_S64:{ S64 left = (S64)b->registers[instr->index_a].s64; S64 result = ~left; S64 *dst = b->registers[instr->index_c].pointer_s64; *dst = result; bc_log("~ [%lld] = [%lld]", left, result); }break; case BC_EQ_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left == right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] == [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_NEQ_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left != right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] != [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_GT_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left > right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] > [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_LT_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left < right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] < [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_OR_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left || right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] || [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_GTE_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left >= right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] >= [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_LTE_S64:{ S64 left = b->registers[instr->index_a].s64; S64 right = b->registers[instr->index_b].s64; S64 result = left <= right; b->registers[instr->index_c].s64 = result; bc_log("r%u + r%u = r%u => [%lld] <= [%lld] = [%lld]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_ADD_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left + right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] + [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_SUB_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left - right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] - [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_DIV_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left / right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] / [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_MUL_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left * right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] * [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_MOD_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left % right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] % [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_SHR_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left >> right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] >> [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_SHL_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left << right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] << [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_BITAND_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left & right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] & [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_BITOR_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left | right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] | [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_BITXOR_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left ^ right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] ^ [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_BITNOT_U64:{ U64 left = (U64)b->registers[instr->index_a].u64; U64 result = ~left; U64 *dst = b->registers[instr->index_c].pointer_u64; *dst = result; bc_log("~ [%llu] = [%llu]", left, result); }break; case BC_EQ_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left == right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] == [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_NEQ_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left != right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] != [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_GT_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left > right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] > [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_LT_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left < right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] < [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_OR_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left || right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] || [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_GTE_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left >= right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] >= [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_LTE_U64:{ U64 left = b->registers[instr->index_a].u64; U64 right = b->registers[instr->index_b].u64; U64 result = left <= right; b->registers[instr->index_c].u64 = result; bc_log("r%u + r%u = r%u => [%llu] <= [%llu] = [%llu]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_ADD_F64:{ F64 left = b->registers[instr->index_a].f64; F64 right = b->registers[instr->index_b].f64; F64 result = left + right; b->registers[instr->index_c].f64 = result; bc_log("r%u + r%u = r%u => [%f] + [%f] = [%f]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_SUB_F64:{ F64 left = b->registers[instr->index_a].f64; F64 right = b->registers[instr->index_b].f64; F64 result = left - right; b->registers[instr->index_c].f64 = result; bc_log("r%u + r%u = r%u => [%f] - [%f] = [%f]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_DIV_F64:{ F64 left = b->registers[instr->index_a].f64; F64 right = b->registers[instr->index_b].f64; F64 result = left / right; b->registers[instr->index_c].f64 = result; bc_log("r%u + r%u = r%u => [%f] / [%f] = [%f]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_MUL_F64:{ F64 left = b->registers[instr->index_a].f64; F64 right = b->registers[instr->index_b].f64; F64 result = left * right; b->registers[instr->index_c].f64 = result; bc_log("r%u + r%u = r%u => [%f] * [%f] = [%f]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_EQ_F64:{ F64 left = b->registers[instr->index_a].f64; F64 right = b->registers[instr->index_b].f64; F64 result = left == right; b->registers[instr->index_c].f64 = result; bc_log("r%u + r%u = r%u => [%f] == [%f] = [%f]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_NEQ_F64:{ F64 left = b->registers[instr->index_a].f64; F64 right = b->registers[instr->index_b].f64; F64 result = left != right; b->registers[instr->index_c].f64 = result; bc_log("r%u + r%u = r%u => [%f] != [%f] = [%f]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_GT_F64:{ F64 left = b->registers[instr->index_a].f64; F64 right = b->registers[instr->index_b].f64; F64 result = left > right; b->registers[instr->index_c].f64 = result; bc_log("r%u + r%u = r%u => [%f] > [%f] = [%f]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_LT_F64:{ F64 left = b->registers[instr->index_a].f64; F64 right = b->registers[instr->index_b].f64; F64 result = left < right; b->registers[instr->index_c].f64 = result; bc_log("r%u + r%u = r%u => [%f] < [%f] = [%f]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_GTE_F64:{ F64 left = b->registers[instr->index_a].f64; F64 right = b->registers[instr->index_b].f64; F64 result = left >= right; b->registers[instr->index_c].f64 = result; bc_log("r%u + r%u = r%u => [%f] >= [%f] = [%f]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; case BC_LTE_F64:{ F64 left = b->registers[instr->index_a].f64; F64 right = b->registers[instr->index_b].f64; F64 result = left <= right; b->registers[instr->index_c].f64 = result; bc_log("r%u + r%u = r%u => [%f] <= [%f] = [%f]", instr->index_a, instr->index_b, instr->index_c, left, right, result); }break; // // **End** of generated using code_generating_script.py // } bc_log("\n"); } end_of_program:; }