Remove old files

This commit is contained in:
Krzosa Karol
2022-08-26 21:50:47 +02:00
parent 3857a0b939
commit eb4b1eca38
4 changed files with 1 additions and 370 deletions

View File

@@ -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)

View File

@@ -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"

View File

@@ -1,190 +0,0 @@
#include <stdio.h>
#include <stdint.h>
#include <windows.h>
#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);
}