From eb4b1eca387c6237b78562aea1ebd62921ab1f2f Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Fri, 26 Aug 2022 21:50:47 +0200 Subject: [PATCH] Remove old files --- big_int_c3.cpp => c3_big_int.cpp | 0 code_generating_script.py | 179 ----------------------------- main.cpp | 2 +- x64_funtime.cpp | 190 ------------------------------- 4 files changed, 1 insertion(+), 370 deletions(-) rename big_int_c3.cpp => c3_big_int.cpp (100%) delete mode 100644 code_generating_script.py delete mode 100644 x64_funtime.cpp diff --git a/big_int_c3.cpp b/c3_big_int.cpp similarity index 100% rename from big_int_c3.cpp rename to c3_big_int.cpp diff --git a/code_generating_script.py b/code_generating_script.py deleted file mode 100644 index 28e8759..0000000 --- a/code_generating_script.py +++ /dev/null @@ -1,179 +0,0 @@ -sizes = ["64", "32", "16", "8"] -types = ["S64", "U64", "F64"] -print_sign = ["%lld", "%llu", "%f"] -operations = [ - ["+", "ADD"], ["-", "SUB"], ["/", "DIV"], ["*", "MUL"], ["%", "MOD"], - [">>", "SHR"], ["<<", "SHL"], ["&", "BITAND"], ["|", "BITOR"], ["^", "BITXOR"], - ["~", "BITNOT"], ["==", "EQ"], ["!=", "NEQ"], [">", "GT"], ["<", "LT"], ["||", "OR"], - [">=", "GTE"], ["<=", "LTE"] -] - -def should_skip(T, op): - if T == "F64": - if op != "DIV" and op != "SUB" and op != "ADD" and op != "MUL" and op != "EQ" and op != "NEQ"\ - and op != "GT" and op != "LT" and op != "GTE" and op != "LTE": - return True - -# This function inserts generated code into the specified file -# it requires a specific comment to be triggered. -# Lossing data would be terrible so we also backup that file -# in case something bad happens -def update_file(filename, comment_name, data_to_write): - begin = f"""// -// *Begin* of {comment_name} generated using code_generating_script.py -// -""" - end = f""" -// -// *End* of {comment_name} generated using code_generating_script.py -//""" - - with open(filename, 'r+') as file: - data = file.read() - file.seek(0) - - begin_index = data.find(begin) - end_index = data.find(end) - if begin_index == -1 or end_index == -1: - print(f"Error: Couldn't find comment: {comment_name}") - exit(0) - - end_index += len(end) - - with open('backup', 'a') as backup: - backup.write(f"\n*** FILE = {filename} NAME = {comment_name} ***") - backup.write(f"\n*** FILE = {filename} NAME = {comment_name} ***") - backup.write(f"\n*** FILE = {filename} NAME = {comment_name} ***") - backup.write(data) - - a_part = data[0:begin_index] - b_part = data[begin_index:end_index] - c_part = data[end_index:len(data)] - - data_to_write = begin + data_to_write + end - - file.write(a_part + data_to_write + c_part) - file.truncate() - - - -if False: - result = "" - enum_members = [ - "BC_END_OF_INSTRUCTIONS", - "BC_POP_STACK", - "BC_PUSH_STACK", - "BC_LOAD_CONSTANT", - "BC_STORE_CONSTANT", - "BC_CALL", - "BC_CALL_RETURN", - ] - - load_store = ["LOAD_FROM_MEMORY", "STORE_TO_MEMORY"] - for op in load_store: - for size in sizes: - enum_members.append(f"BC_{op}{size}") - - for T in types: - for _, op in operations: - if should_skip(T, op): - continue - enum_members.append(f"BC_{op}_{T}") - - result += "enum Operation: U16{\n" - for i in enum_members: - result += f" {i},\n" - result += "};\n" - - result += "const char *op_name[] = {\n" - for i in enum_members: - result += f" \"{i}\",\n" - result += "};\n" - update_file("bytecode_interpreter.cpp", "enum", result) - - - -# -# Generate switch cases -# -if False: - result = "" - - for size in sizes: - result += f""" - case BC_LOAD_FROM_MEMORY{size}:{{ - U{size} *load_address = R(instr->index_a).pointer_u{size}; - R(instr->index_c).u{size} = *load_address; - bc_log("load_address[r%u, %llx] dst[r%u] [0x%llx|%lld|%f]", instr->index_a, load_address, instr->index_c, R(instr->index_c).u{size}, R(instr->index_c).u{size}, R(instr->index_c).u{size}); - }}break; - - case BC_STORE_TO_MEMORY{size}:{{ - U{size} *store_address = R(instr->index_c).pointer_u{size}; - *store_address = R(instr->index_a).u{size}; - 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; - """ - - for sign, T in zip(print_sign, types): - t = T.lower() - - # Generate arithmetic - for symbol, op_name in operations: - if should_skip(T, op_name): - continue - - ################################### - # Unary operator special case - if symbol == "~": - result += f""" - case BC_{op_name}_{T}:{{ - {T} left = ({T})R(instr->index_a).{t}; - {T} result = {symbol}left; - {T} *dst = R(instr->index_c).pointer_{t}; - *dst = result; - bc_log("{symbol} [{sign}] = [{sign}]", left, result); - }}break; - """ - continue - ################################ - - ################################ - # Binary operation - result += f""" - case BC_{op_name}_{T}:{{ - {T} left = R(instr->index_a).{t}; - {T} right = R(instr->index_b).{t}; - {T} result = left {symbol} right; - R(instr->index_c).{t} = result; - bc_log("[r%d, {sign}] {symbol} [r%d, {sign}] = [r%d, {sign}]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }}break; - """ - ################################ - update_file("bytecode_interpreter.cpp", "switch_cases", result) - - -type_table = [ - ["S", ["Int", "SInt", "4sizes"]], - ["U", ["Int", "UInt", "4sizes"]], - ["INT", ["Int", "untyped"]], -] - -for name, flags in type_table: - names = [] - if "4sizes" in flags: - for size in sizes: - names.append(name + size) - if "untyped" in flags: - names.append("UNTYPED_" + name) - - print(names) - - - - - -# # -# # Copy backup to **WINDOWS** clipboard -# # -# import subprocess -# subprocess.run("clip", universal_newlines=True, input=data) diff --git a/main.cpp b/main.cpp index f0a252a..91dab3a 100644 --- a/main.cpp +++ b/main.cpp @@ -103,7 +103,7 @@ For modules it's a bit different cause they should be distributed as valid. #include "base.cpp" #include "base_unicode.cpp" #include "os_windows.cpp" -#include "big_int_c3.cpp" +#include "c3_big_int.cpp" #include "compiler.h" #include "lexing.cpp" #include "types.h" diff --git a/x64_funtime.cpp b/x64_funtime.cpp deleted file mode 100644 index b926cdf..0000000 --- a/x64_funtime.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include -#include -#include - -#define assert(x) do{if(!(x))__debugbreak();}while(0) -#define assert_in_range(x, a, b) assert(((x) >= a) && ((x) <= b)) -#define assert_is_one(x) assert_in_range(x, 0, 1) - -uint8_t* code_start; -uint8_t* code; - -void emit(uint8_t c) { - *code++ = c; -} - -void emit32(uint32_t c) { - *(uint32_t*)code = c; - code += 4; -} - -// Prefix ordering in X64: -// 1. Legacy prefixes (optional) -// 2. REX prefix (optional) -// 3. Opcode (1 or 2 or 3 bytes) -// 4. ModR/M (1 byte if required) -// 5. SIB (1 byte if required) -// 6. Displacement (1 or 2 or 4 bytes) -// 7. Immediate (1 or 2 or 4 bytes) - -// Basic op codes -const uint8_t OP_BREAK = 0xCC; -const uint8_t OP_RETURN = 0xC3; - -// From manual: -// The operand-size override prefix allows a program to switch between 16-and 32-bit operand sizes. Either size can -// be the default; use of the prefix selects the non-default size. -// When using the REX prefix, adding this changes the operand size to 32bits -const uint8_t OPERAND_SIZE_OVERRIDE = 0x66; -const uint8_t GS_SEGMENT_OVERRIDE = 0x65; - -// Registers -// al(8lo), ah(8hi), ax(16), eax(32), rax(64) -enum{RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15}; -typedef uint8_t Register; - -// REX - 64 bit mode prefix -// we write this when -// * instruction references extended(64bit) register -// * uses a 64 bit operand. -// W 1 bit When 1, a 64 - bit operand size is used. Otherwise, when 0, the default operand size is used(which is 32 - bit for most but not all instructions, see this table). -// R 1 bit This 1 - bit value is an extension to the MODRM.reg field.See Registers. -// X 1 bit This 1 - bit value is an extension to the SIB.index field.See 64 - bit addressing. -// B 1 bit This 1 - bit value is an extension to the MODRM.rm field or the SIB.base field.See 64 - bit addressing. -uint8_t rex(uint8_t w, uint8_t r, uint8_t x, uint8_t b) { - assert_is_one(w); assert_is_one(r); - assert_is_one(x); assert_is_one(b); - return 0b0100 << 4 | w << 3 | r << 2 | x << 1 | b; -} -#define REX_W rex(1,0,0,0) - -// ModR/M -// -// Addressing -// - Indirect : operand is stored under the address specified by one of the registers -// - Displaced: operand is stored under the displaced(offset) address specified by one of the registers, [rsp + 32h] other example: [rsp + rax*2 + 32], we use 2 registers - keyword SIB -// - Register : operand is stored in the register -// - Immediate: operand is stored right in the instruction, seems like existence of immeadiate depends on the instruction -enum{ // modr/m modes - MODE_INDIRECT_ADDRESSING = 0, - MODE_DISPLACED8_ADDRESSING = 1, - MODE_DISPLACED32_ADDRESSING = 2, - MODE_DISPLACED16_ADDRESSING = 2, - MODE_REGISTER_ADDRESSING = 3, -}; - -// SIB Addressing -// 7-6 bits for scale (1, 2, 4, 8) -// 5-3 register with index (index * scale) -// 2-0 register with base base + (index * scale) -const uint8_t SIB_SCALE1 = 0; -const uint8_t SIB_SCALE2 = 1; -const uint8_t SIB_SCALE4 = 2; -const uint8_t SIB_SCALE8 = 3; -const uint8_t MODRM_RM_SIB = 4; - -// reg, rm - specify 3 bit register -// to address extended registers r8 - r15, you need to set proper REX bit -uint8_t modrm(uint8_t mode, uint8_t reg, uint8_t rm) { - assert_in_range(mode, 0, 3); - assert_in_range(reg, 0, 7); - assert_in_range(rm, 0, 7); - return (mode << 6) | (reg << 3) | rm; -} - -// We need to set appropriate flag on the rex value to -// use extended registers -uint8_t adjust_registers_and_get_rex(Register *rm, Register *rx) { - uint8_t rex_value = REX_W; - assert_in_range(*rm, 0, 15); - assert_in_range(*rx, 0, 15); - - if (*rm >= 8) { - rex_value |= 1 << 2; - *rm -= 8; - } - - if (*rx >= 8) { - rex_value |= 1; - *rx -= 8; - } - - return rex_value; -} - -// add rax, rcx => emit_register_op(0x03, RAX, RCX) -void emit_register_op(uint8_t op_code, Register rm, Register rx) { - uint8_t rex_value = adjust_registers_and_get_rex(&rm, &rx); - - emit(rex_value); - emit(op_code); - emit(modrm(MODE_REGISTER_ADDRESSING, rm, rx)); -} - -// add rax, [rcx] => emit_indirect_op(0x03, RAX, RCX); -void emit_indirect_op(uint8_t op_code, Register rx, Register rm) { - assert(rx != RSP); // SIB - assert(rx != 8 + RSP); // SIB // R12 - assert(rx != RBP); // Displacement32 - assert(rx != 8 + RBP); // Displacement32 // R13 - - uint8_t rex_value = adjust_registers_and_get_rex(&rm, &rx); - emit(rex_value); - emit(op_code); - emit(modrm(MODE_INDIRECT_ADDRESSING, rm, rx)); -} - -void emit_indirect_displaced8_op(uint8_t op_code, Register rx, Register rm, uint8_t displacement) { - assert(rx != RSP); // SIB - assert(rx != 8 + RSP); // SIB // R12 - - uint8_t rex_value = adjust_registers_and_get_rex(&rm, &rx); - emit(rex_value); - emit(op_code); - emit(modrm(MODE_DISPLACED8_ADDRESSING, rm, rx)); - emit(displacement); -} - -void emit_indirect_displaced32_op(uint8_t op_code, Register rx, Register rm, uint32_t displacement) { - assert(rx != RSP); // SIB - assert(rx != 8 + RSP); // SIB // R12 - - uint8_t rex_value = adjust_registers_and_get_rex(&rm, &rx); - emit(rex_value); - emit(op_code); - emit(modrm(MODE_DISPLACED32_ADDRESSING, rm, rx)); - emit32(displacement); -} - - -// extern "C" void asm_test(); -void test_x64_stuff() { - //asm_test(); - - code = code_start = (uint8_t*)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - emit(OP_BREAK); - - // REX.W + F7 /4 - #if 0 - emit(REX_W); - emit(0xF7); - emit(modrm(MODE_REGISTER_ADDRESSING, 0x4, RCX)); - #endif - - for (Register dst = RAX; dst <= R15; dst++) { - for (Register src = RAX; src <= R15; src++) { - if ((dst & 7) != RSP) { - emit_indirect_displaced32_op(0x03, dst, src, 0xffffff); - emit_indirect_displaced8_op(0x03, dst, src, 0x32); - } - if ((dst & 7) != RSP && (dst & 7) != RBP) - emit_indirect_op(0x03, dst, src); - emit_register_op(0x03, dst, src); - } - } - - emit(OP_RETURN); - - auto add = (uint64_t(*)(uint64_t, uint64_t))code_start; - uint64_t result = add(11, 22); -} \ No newline at end of file