mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-14 14:23:43 +00:00
Begin updating Tilde
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
#include "tilde.hpp"
|
||||
|
||||
|
||||
gb_global Slice<TB_Arena> global_tb_arenas;
|
||||
gb_global Slice<TB_Arena *> global_tb_arenas;
|
||||
|
||||
gb_internal TB_Arena *cg_arena(void) {
|
||||
return &global_tb_arenas[current_thread_index()];
|
||||
return global_tb_arenas[current_thread_index()];
|
||||
}
|
||||
|
||||
gb_internal void cg_global_arena_init(void) {
|
||||
global_tb_arenas = slice_make<TB_Arena>(permanent_allocator(), global_thread_pool.threads.count);
|
||||
global_tb_arenas = slice_make<TB_Arena *>(permanent_allocator(), global_thread_pool.threads.count);
|
||||
for_array(i, global_tb_arenas) {
|
||||
tb_arena_create(&global_tb_arenas[i], 2ull<<20);
|
||||
global_tb_arenas[i] = tb_arena_create(2ull<<20);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ gb_internal cgValue cg_value(TB_Node *node, Type *type) {
|
||||
return v;
|
||||
}
|
||||
gb_internal cgValue cg_lvalue_addr(TB_Node *node, Type *type) {
|
||||
GB_ASSERT(node->dt.type == TB_PTR);
|
||||
GB_ASSERT(node->dt.type == TB_TAG_PTR);
|
||||
cgValue v = {};
|
||||
v.kind = cgValue_Addr;
|
||||
v.type = type;
|
||||
@@ -136,10 +136,10 @@ gb_internal cgValue cg_lvalue_addr(TB_Node *node, Type *type) {
|
||||
gb_internal cgValue cg_lvalue_addr_to_value(cgValue v) {
|
||||
if (v.kind == cgValue_Value) {
|
||||
GB_ASSERT(is_type_pointer(v.type));
|
||||
GB_ASSERT(v.node->dt.type == TB_PTR);
|
||||
GB_ASSERT(v.node->dt.type == TB_TAG_PTR);
|
||||
} else {
|
||||
GB_ASSERT(v.kind == cgValue_Addr);
|
||||
GB_ASSERT(v.node->dt.type == TB_PTR);
|
||||
GB_ASSERT(v.node->dt.type == TB_TAG_PTR);
|
||||
v.kind = cgValue_Value;
|
||||
v.type = alloc_type_pointer(v.type);
|
||||
}
|
||||
@@ -440,9 +440,8 @@ gb_internal cgModule *cg_module_create(Checker *c) {
|
||||
m->info = &c->info;
|
||||
|
||||
|
||||
TB_FeatureSet feature_set = {};
|
||||
bool is_jit = false;
|
||||
m->mod = tb_module_create(TB_ARCH_X86_64, TB_SYSTEM_WINDOWS, &feature_set, is_jit);
|
||||
m->mod = tb_module_create(TB_ARCH_X86_64, TB_SYSTEM_WINDOWS, is_jit);
|
||||
tb_module_set_tls_index(m->mod, 10, "_tls_index");
|
||||
|
||||
map_init(&m->values);
|
||||
@@ -464,8 +463,7 @@ gb_internal cgModule *cg_module_create(Checker *c) {
|
||||
|
||||
for_array(id, global_files) {
|
||||
if (AstFile *f = global_files[id]) {
|
||||
char const *path = alloc_cstring(temporary_allocator(), f->fullpath);
|
||||
TB_SourceFile *file = tb_get_source_file(m->mod, path);
|
||||
TB_SourceFile *file = tb_get_source_file(m->mod, f->fullpath.len, cast(char const *)f->fullpath.text);
|
||||
map_set(&m->file_id_map, cast(uintptr)id, file);
|
||||
}
|
||||
}
|
||||
@@ -830,8 +828,8 @@ gb_internal bool cg_generate_code(Checker *c, LinkerData *linker_data) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
TB_ExportBuffer export_buffer = tb_module_object_export(m->mod, debug_format);
|
||||
defer (tb_export_buffer_free(export_buffer));
|
||||
TB_ExportBuffer export_buffer = tb_module_object_export(m->mod, cg_arena(), debug_format);
|
||||
// defer (tb_export_buffer_free(export_buffer)); // THIS IS MISSING
|
||||
|
||||
String filepath_obj = cg_filepath_obj_for_module(m, false);
|
||||
array_add(&linker_data->output_object_paths, filepath_obj);
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
#endif
|
||||
|
||||
#include "tilde/tb.h"
|
||||
#include "tilde/tb_arena.h"
|
||||
|
||||
#define TB_TYPE_F16 TB_DataType{ { TB_INT, 16 } }
|
||||
#define TB_TYPE_I128 TB_DataType{ { TB_INT, 128 } }
|
||||
#define TB_TYPE_F16 TB_DataType{ { TB_TAG_INT, 16 } }
|
||||
#define TB_TYPE_I128 TB_DataType{ { TB_TAG_INT, 128 } }
|
||||
#define TB_TYPE_INT TB_TYPE_INTN(cast(u16)(8*build_context.int_size))
|
||||
#define TB_TYPE_INTPTR TB_TYPE_INTN(cast(u16)(8*build_context.ptr_size))
|
||||
|
||||
|
||||
724
src/tilde/tb.h
724
src/tilde/tb.h
File diff suppressed because it is too large
Load Diff
BIN
src/tilde/tb.lib
BIN
src/tilde/tb.lib
Binary file not shown.
@@ -1,79 +0,0 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef TB_API
|
||||
# ifdef __cplusplus
|
||||
# define TB_EXTERN extern "C"
|
||||
# else
|
||||
# define TB_EXTERN
|
||||
# endif
|
||||
# ifdef TB_DLL
|
||||
# ifdef TB_IMPORT_DLL
|
||||
# define TB_API TB_EXTERN __declspec(dllimport)
|
||||
# else
|
||||
# define TB_API TB_EXTERN __declspec(dllexport)
|
||||
# endif
|
||||
# else
|
||||
# define TB_API TB_EXTERN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
enum {
|
||||
TB_ARENA_SMALL_CHUNK_SIZE = 4 * 1024,
|
||||
TB_ARENA_MEDIUM_CHUNK_SIZE = 512 * 1024,
|
||||
TB_ARENA_LARGE_CHUNK_SIZE = 16 * 1024 * 1024,
|
||||
|
||||
TB_ARENA_ALIGNMENT = 16,
|
||||
};
|
||||
|
||||
typedef struct TB_ArenaChunk TB_ArenaChunk;
|
||||
struct TB_ArenaChunk {
|
||||
TB_ArenaChunk* next;
|
||||
size_t pad;
|
||||
char data[];
|
||||
};
|
||||
|
||||
typedef struct TB_Arena {
|
||||
size_t chunk_size;
|
||||
TB_ArenaChunk* base;
|
||||
TB_ArenaChunk* top;
|
||||
|
||||
// top of the allocation space
|
||||
char* watermark;
|
||||
char* high_point; // &top->data[chunk_size]
|
||||
} TB_Arena;
|
||||
|
||||
typedef struct TB_ArenaSavepoint {
|
||||
TB_ArenaChunk* top;
|
||||
char* watermark;
|
||||
} TB_ArenaSavepoint;
|
||||
|
||||
#define TB_ARENA_FOR(it, arena) for (TB_ArenaChunk* it = (arena)->base; it != NULL; it = it->next)
|
||||
|
||||
#define TB_ARENA_ALLOC(arena, T) tb_arena_alloc(arena, sizeof(T))
|
||||
#define TB_ARENA_ARR_ALLOC(arena, count, T) tb_arena_alloc(arena, (count) * sizeof(T))
|
||||
|
||||
TB_API void tb_arena_create(TB_Arena* restrict arena, size_t chunk_size);
|
||||
TB_API void tb_arena_destroy(TB_Arena* restrict arena);
|
||||
|
||||
TB_API void* tb_arena_unaligned_alloc(TB_Arena* restrict arena, size_t size);
|
||||
TB_API void* tb_arena_alloc(TB_Arena* restrict arena, size_t size);
|
||||
|
||||
// return false on failure
|
||||
TB_API bool tb_arena_free(TB_Arena* restrict arena, void* ptr, size_t size);
|
||||
TB_API void tb_arena_pop(TB_Arena* restrict arena, void* ptr, size_t size);
|
||||
|
||||
// in case you wanna mix unaligned and aligned arenas
|
||||
TB_API void tb_arena_realign(TB_Arena* restrict arena);
|
||||
|
||||
TB_API bool tb_arena_is_empty(TB_Arena* arena);
|
||||
|
||||
TB_API size_t tb_arena_current_size(TB_Arena* arena);
|
||||
|
||||
// savepoints
|
||||
TB_API TB_ArenaSavepoint tb_arena_save(TB_Arena* arena);
|
||||
TB_API void tb_arena_restore(TB_Arena* arena, TB_ArenaSavepoint sp);
|
||||
|
||||
// resets to only having one chunk
|
||||
TB_API void tb_arena_clear(TB_Arena* arena);
|
||||
@@ -220,11 +220,11 @@ bool tb_coff_parse_section(TB_COFF_Parser* restrict parser, size_t i, TB_ObjectS
|
||||
}
|
||||
|
||||
const uint8_t* data = &parser->string_table.data[offset];
|
||||
out_sec->name = (TB_Slice){ strlen((const char*) data), data };
|
||||
out_sec->name = (TB_Slice){ data, strlen((const char*) data) };
|
||||
} else {
|
||||
// normal inplace string
|
||||
size_t len = strlen(sec->name);
|
||||
out_sec->name = (TB_Slice){ len, (uint8_t*) sec->name };
|
||||
out_sec->name = (TB_Slice){ (uint8_t*) sec->name, len };
|
||||
}
|
||||
|
||||
// Parse relocations
|
||||
@@ -233,7 +233,7 @@ bool tb_coff_parse_section(TB_COFF_Parser* restrict parser, size_t i, TB_ObjectS
|
||||
COFF_ImageReloc* src_relocs = (COFF_ImageReloc*) &file.data[sec->pointer_to_reloc];
|
||||
|
||||
TB_ObjectReloc* dst_relocs = tb_platform_heap_alloc(sec->num_reloc * sizeof(TB_ObjectReloc));
|
||||
FOREACH_N(j, 0, sec->num_reloc) {
|
||||
FOR_N(j, 0, sec->num_reloc) {
|
||||
dst_relocs[j] = (TB_ObjectReloc){ 0 };
|
||||
switch (src_relocs[j].Type) {
|
||||
case IMAGE_REL_AMD64_ADDR32NB: dst_relocs[j].type = TB_OBJECT_RELOC_ADDR32NB; break;
|
||||
@@ -272,7 +272,7 @@ bool tb_coff_parse_section(TB_COFF_Parser* restrict parser, size_t i, TB_ObjectS
|
||||
// Read raw data (if applies)
|
||||
if (sec->raw_data_size) {
|
||||
assert(sec->raw_data_pos + sec->raw_data_size < file.length);
|
||||
out_sec->raw_data = (TB_Slice){ sec->raw_data_size, &file.data[sec->raw_data_pos] };
|
||||
out_sec->raw_data = (TB_Slice){ &file.data[sec->raw_data_pos], sec->raw_data_size };
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -310,7 +310,7 @@ size_t tb_coff_parse_symbol(TB_COFF_Parser* restrict parser, size_t i, TB_Object
|
||||
// string table access (read a cstring)
|
||||
// TODO(NeGate): bounds check this
|
||||
const uint8_t* data = &parser->string_table.data[sym->long_name[1]];
|
||||
out_sym->name = (TB_Slice){ strlen((const char*) data), data };
|
||||
out_sym->name = (TB_Slice){ data, strlen((const char*) data) };
|
||||
} else {
|
||||
// normal inplace string
|
||||
size_t len = 1;
|
||||
@@ -318,14 +318,14 @@ size_t tb_coff_parse_symbol(TB_COFF_Parser* restrict parser, size_t i, TB_Object
|
||||
while (len < 8 && name[len] != 0) {
|
||||
len++;
|
||||
}
|
||||
out_sym->name = (TB_Slice){ len, sym->short_name };
|
||||
out_sym->name = (TB_Slice){ sym->short_name, len };
|
||||
}
|
||||
|
||||
// TODO(NeGate): Process aux symbols
|
||||
if (sym->aux_symbols_count) {
|
||||
out_sym->extra = &sym[1];
|
||||
|
||||
// FOREACH_N(j, 0, sym->aux_symbols_count) {}
|
||||
// FOR_N(j, 0, sym->aux_symbols_count) {}
|
||||
}
|
||||
|
||||
return sym->aux_symbols_count + 1;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
/* Values for e_machine. */
|
||||
#define TB_EM_NONE 0 /* Unknown machine. */
|
||||
#define TB_EM_MIPS 8 /* Mips */
|
||||
#define TB_EM_X86_64 62 /* Advanced Micro Devices x86-64 */
|
||||
#define TB_EM_AARCH64 183 /* AArch64 (64-bit ARM) */
|
||||
|
||||
|
||||
@@ -4,36 +4,41 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef TB_API
|
||||
# ifdef __cplusplus
|
||||
# define TB_EXTERN extern "C"
|
||||
# else
|
||||
# define TB_EXTERN
|
||||
# endif
|
||||
# ifdef TB_DLL
|
||||
# ifdef TB_IMPORT_DLL
|
||||
# define TB_API TB_EXTERN __declspec(dllimport)
|
||||
# else
|
||||
# define TB_API TB_EXTERN __declspec(dllexport)
|
||||
# endif
|
||||
# else
|
||||
# define TB_API TB_EXTERN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
// uses xmm registers for the reg array
|
||||
TB_X86_INSTR_XMMREG = (1u << 0u),
|
||||
|
||||
// r/m is a memory operand
|
||||
TB_X86_INSTR_USE_MEMOP = (1u << 1u),
|
||||
|
||||
// r/m is a rip-relative address (TB_X86_INSTR_USE_MEMOP is always set when this is set)
|
||||
TB_X86_INSTR_USE_RIPMEM = (1u << 2u),
|
||||
TB_X86_INSTR_INDIRECT = (1u << 0u),
|
||||
|
||||
// LOCK prefix is present
|
||||
TB_X86_INSTR_LOCK = (1u << 3u),
|
||||
TB_X86_INSTR_LOCK = (1u << 1u),
|
||||
|
||||
// uses a signed immediate
|
||||
TB_X86_INSTR_IMMEDIATE = (1u << 4u),
|
||||
|
||||
// absolute means it's using the 64bit immediate (cannot be applied while a memory operand is active)
|
||||
TB_X86_INSTR_ABSOLUTE = (1u << 5u),
|
||||
// uses an immediate
|
||||
TB_X86_INSTR_IMMEDIATE = (1u << 2u),
|
||||
|
||||
// set if the r/m can be found on the right hand side
|
||||
TB_X86_INSTR_DIRECTION = (1u << 6u),
|
||||
|
||||
// uses the second data type because the instruction is weird like MOVSX or MOVZX
|
||||
TB_X86_INSTR_TWO_DATA_TYPES = (1u << 7u),
|
||||
TB_X86_INSTR_DIRECTION = (1u << 3u),
|
||||
|
||||
// REP prefix is present
|
||||
TB_X86_INSTR_REP = (1u << 8u),
|
||||
TB_X86_INSTR_REP = (1u << 5u),
|
||||
|
||||
// REPNE prefix is present
|
||||
TB_X86_INSTR_REPNE = (1u << 9u),
|
||||
TB_X86_INSTR_REPNE = (1u << 6u),
|
||||
} TB_X86_InstFlags;
|
||||
|
||||
typedef enum {
|
||||
@@ -50,56 +55,53 @@ typedef enum {
|
||||
} TB_X86_Segment;
|
||||
|
||||
typedef enum {
|
||||
TB_X86_TYPE_NONE = 0,
|
||||
TB_X86_NONE = 0,
|
||||
|
||||
TB_X86_TYPE_BYTE, // 1
|
||||
TB_X86_TYPE_WORD, // 2
|
||||
TB_X86_TYPE_DWORD, // 4
|
||||
TB_X86_TYPE_QWORD, // 8
|
||||
TB_X86_BYTE, // 1
|
||||
TB_X86_WORD, // 2
|
||||
TB_X86_DWORD, // 4
|
||||
TB_X86_QWORD, // 8
|
||||
|
||||
TB_X86_TYPE_PBYTE, // int8 x 16 = 16
|
||||
TB_X86_TYPE_PWORD, // int16 x 8 = 16
|
||||
TB_X86_TYPE_PDWORD, // int32 x 4 = 16
|
||||
TB_X86_TYPE_PQWORD, // int64 x 2 = 16
|
||||
TB_X86_PBYTE, // int8 x 16 = 16
|
||||
TB_X86_PWORD, // int16 x 8 = 16
|
||||
TB_X86_PDWORD, // int32 x 4 = 16
|
||||
TB_X86_PQWORD, // int64 x 2 = 16
|
||||
|
||||
TB_X86_TYPE_SSE_SS, // float32 x 1 = 4
|
||||
TB_X86_TYPE_SSE_SD, // float64 x 1 = 8
|
||||
TB_X86_TYPE_SSE_PS, // float32 x 4 = 16
|
||||
TB_X86_TYPE_SSE_PD, // float64 x 2 = 16
|
||||
TB_X86_F32x1, // ss
|
||||
TB_X86_F64x1, // sd
|
||||
TB_X86_F32x4, // ps
|
||||
TB_X86_F64x2, // pd
|
||||
|
||||
TB_X86_TYPE_XMMWORD, // the generic idea of them
|
||||
TB_X86_XMMWORD, // the generic idea of them
|
||||
} TB_X86_DataType;
|
||||
|
||||
typedef struct {
|
||||
int32_t opcode;
|
||||
uint16_t opcode;
|
||||
|
||||
// registers (there's 4 max taking up 8bit slots each)
|
||||
int8_t regs[4];
|
||||
uint16_t flags;
|
||||
// packed 16bits
|
||||
uint16_t scale : 2;
|
||||
uint16_t flags : 6;
|
||||
uint16_t dt : 4;
|
||||
uint16_t dt2 : 4;
|
||||
|
||||
// bitpacking amirite
|
||||
TB_X86_DataType data_type : 8;
|
||||
TB_X86_DataType data_type2 : 8;
|
||||
TB_X86_Segment segment : 4;
|
||||
uint8_t length : 4;
|
||||
|
||||
// memory operand
|
||||
// X86_INSTR_USE_MEMOP
|
||||
uint8_t base, index, scale;
|
||||
// each 8bits are a different reg (lowest bits to higher):
|
||||
// base, index, rx, extra
|
||||
uint32_t regs;
|
||||
int32_t disp;
|
||||
|
||||
// bitpacking amirite
|
||||
TB_X86_Segment segment : 4;
|
||||
uint8_t length : 4;
|
||||
uint8_t disp_pos : 4;
|
||||
|
||||
// immediate operand
|
||||
// imm for INSTR_IMMEDIATE
|
||||
// abs for INSTR_ABSOLUTE
|
||||
union {
|
||||
int32_t imm;
|
||||
uint64_t abs;
|
||||
};
|
||||
int64_t imm;
|
||||
} TB_X86_Inst;
|
||||
|
||||
bool tb_x86_disasm(TB_X86_Inst* restrict inst, size_t length, const uint8_t* data);
|
||||
const char* tb_x86_reg_name(int8_t reg, TB_X86_DataType dt);
|
||||
const char* tb_x86_type_name(TB_X86_DataType dt);
|
||||
const char* tb_x86_mnemonic(TB_X86_Inst* inst);
|
||||
TB_API void tb_x86_print_inst(FILE* fp, TB_X86_Inst* inst);
|
||||
TB_API bool tb_x86_disasm(TB_X86_Inst* restrict inst, size_t length, const uint8_t* data);
|
||||
TB_API const char* tb_x86_reg_name(int8_t reg, TB_X86_DataType dt);
|
||||
TB_API const char* tb_x86_type_name(TB_X86_DataType dt);
|
||||
TB_API const char* tb_x86_mnemonic(TB_X86_Inst* inst);
|
||||
|
||||
#endif /* TB_X64_H */
|
||||
|
||||
@@ -202,12 +202,10 @@ gb_internal cgValue cg_builtin_abs(cgProcedure *p, cgValue const &x) {
|
||||
TB_DataType dt = cg_data_type(x.type);
|
||||
GB_ASSERT(!TB_IS_VOID_TYPE(dt));
|
||||
TB_Node *zero = nullptr;
|
||||
if (dt.type == TB_FLOAT) {
|
||||
if (dt.data == 32) {
|
||||
zero = tb_inst_float32(p->func, 0);
|
||||
} else if (dt.data == 64) {
|
||||
zero = tb_inst_float64(p->func, 0);
|
||||
}
|
||||
if (dt.type == TB_TAG_F32) {
|
||||
zero = tb_inst_float32(p->func, 0);
|
||||
} else if (dt.type == TB_TAG_F64) {
|
||||
zero = tb_inst_float64(p->func, 0);
|
||||
} else {
|
||||
zero = tb_inst_uint(p->func, dt, 0);
|
||||
}
|
||||
|
||||
@@ -201,8 +201,8 @@ gb_internal TB_DebugType *cg_debug_type_internal(cgModule *m, Type *type) {
|
||||
case Basic_rune: return tb_debug_get_integer(m->mod, is_signed, bits);
|
||||
|
||||
case Basic_f16: return tb_debug_get_integer(m->mod, false, bits);
|
||||
case Basic_f32: return tb_debug_get_float(m->mod, TB_FLT_32);
|
||||
case Basic_f64: return tb_debug_get_float(m->mod, TB_FLT_64);
|
||||
case Basic_f32: return tb_debug_get_float32(m->mod);
|
||||
case Basic_f64: return tb_debug_get_float64(m->mod);
|
||||
|
||||
case Basic_complex32:
|
||||
case Basic_complex64:
|
||||
@@ -295,11 +295,11 @@ gb_internal TB_DebugType *cg_debug_type_internal(cgModule *m, Type *type) {
|
||||
case Basic_u128be: return tb_debug_get_integer(m->mod, is_signed, bits);
|
||||
|
||||
case Basic_f16le: return tb_debug_get_integer(m->mod, false, bits);
|
||||
case Basic_f32le: return tb_debug_get_float(m->mod, TB_FLT_32);
|
||||
case Basic_f64le: return tb_debug_get_float(m->mod, TB_FLT_64);
|
||||
case Basic_f32le: return tb_debug_get_float32(m->mod);
|
||||
case Basic_f64le: return tb_debug_get_float64(m->mod);
|
||||
case Basic_f16be: return tb_debug_get_integer(m->mod, false, bits);
|
||||
case Basic_f32be: return tb_debug_get_float(m->mod, TB_FLT_32);
|
||||
case Basic_f64be: return tb_debug_get_float(m->mod, TB_FLT_64);
|
||||
case Basic_f32be: return tb_debug_get_float32(m->mod);
|
||||
case Basic_f64be: return tb_debug_get_float64(m->mod);
|
||||
}
|
||||
break;
|
||||
case Type_Generic:
|
||||
|
||||
@@ -223,41 +223,45 @@ gb_internal cgValue cg_emit_transmute(cgProcedure *p, cgValue value, Type *type)
|
||||
value.type = type;
|
||||
if (value.node->dt.raw != dt.raw) {
|
||||
switch (value.node->dt.type) {
|
||||
case TB_INT:
|
||||
case TB_TAG_INT:
|
||||
switch (value.node->dt.type) {
|
||||
case TB_INT:
|
||||
case TB_TAG_INT:
|
||||
break;
|
||||
case TB_FLOAT:
|
||||
case TB_TAG_F32:
|
||||
case TB_TAG_F64:
|
||||
value.node = tb_inst_bitcast(p->func, value.node, dt);
|
||||
break;
|
||||
case TB_PTR:
|
||||
case TB_TAG_PTR:
|
||||
value.node = tb_inst_int2ptr(p->func, value.node);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TB_FLOAT:
|
||||
case TB_TAG_F32:
|
||||
case TB_TAG_F64:
|
||||
switch (value.node->dt.type) {
|
||||
case TB_INT:
|
||||
case TB_TAG_INT:
|
||||
value.node = tb_inst_bitcast(p->func, value.node, dt);
|
||||
break;
|
||||
case TB_FLOAT:
|
||||
case TB_TAG_F32:
|
||||
case TB_TAG_F64:
|
||||
break;
|
||||
case TB_PTR:
|
||||
case TB_TAG_PTR:
|
||||
value.node = tb_inst_bitcast(p->func, value.node, TB_TYPE_INTPTR);
|
||||
value.node = tb_inst_int2ptr(p->func, value.node);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TB_PTR:
|
||||
case TB_TAG_PTR:
|
||||
switch (value.node->dt.type) {
|
||||
case TB_INT:
|
||||
case TB_TAG_INT:
|
||||
value.node = tb_inst_ptr2int(p->func, value.node, dt);
|
||||
break;
|
||||
case TB_FLOAT:
|
||||
case TB_TAG_F32:
|
||||
case TB_TAG_F64:
|
||||
value.node = tb_inst_ptr2int(p->func, value.node, TB_TYPE_INTPTR);
|
||||
value.node = tb_inst_bitcast(p->func, value.node, dt);
|
||||
break;
|
||||
case TB_PTR:
|
||||
case TB_TAG_PTR:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -225,7 +225,7 @@ gb_internal void cg_procedure_begin(cgProcedure *p) {
|
||||
}
|
||||
|
||||
TB_ModuleSectionHandle section = tb_module_get_text(p->module->mod);
|
||||
tb_function_set_prototype(p->func, section, p->proto, cg_arena());
|
||||
tb_function_set_prototype(p->func, section, p->proto);
|
||||
|
||||
if (p->body == nullptr) {
|
||||
return;
|
||||
@@ -289,7 +289,7 @@ gb_internal void cg_procedure_begin(cgProcedure *p) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GB_ASSERT(param_ptr->dt.type == TB_PTR);
|
||||
GB_ASSERT(param_ptr->dt.type == TB_TAG_PTR);
|
||||
|
||||
cgValue local = cg_value(param_ptr, alloc_type_pointer(e->type));
|
||||
|
||||
@@ -368,49 +368,50 @@ gb_internal void cg_procedure_begin(cgProcedure *p) {
|
||||
|
||||
gb_internal WORKER_TASK_PROC(cg_procedure_compile_worker_proc) {
|
||||
cgProcedure *p = cast(cgProcedure *)data;
|
||||
gb_unused(p);
|
||||
|
||||
TB_Passes *opt = tb_pass_enter(p->func, cg_arena());
|
||||
defer (tb_pass_exit(opt));
|
||||
// TB_Passes *opt = tb_pass_enter(p->func, cg_arena());
|
||||
// defer (tb_pass_exit(opt));
|
||||
|
||||
// optimization passes
|
||||
if (false) {
|
||||
tb_pass_peephole(opt, TB_PEEPHOLE_ALL);
|
||||
tb_pass_mem2reg(opt);
|
||||
tb_pass_peephole(opt, TB_PEEPHOLE_ALL);
|
||||
}
|
||||
// // optimization passes
|
||||
// if (false) {
|
||||
// tb_pass_peephole(opt, TB_PEEPHOLE_ALL);
|
||||
// tb_pass_mem2reg(opt);
|
||||
// tb_pass_peephole(opt, TB_PEEPHOLE_ALL);
|
||||
// }
|
||||
|
||||
bool emit_asm = false;
|
||||
if (
|
||||
// string_starts_with(p->name, str_lit("runtime@_windows_default_alloc_or_resize")) ||
|
||||
false
|
||||
) {
|
||||
emit_asm = true;
|
||||
}
|
||||
// bool emit_asm = false;
|
||||
// if (
|
||||
// // string_starts_with(p->name, str_lit("runtime@_windows_default_alloc_or_resize")) ||
|
||||
// false
|
||||
// ) {
|
||||
// emit_asm = true;
|
||||
// }
|
||||
|
||||
// emit ir
|
||||
if (
|
||||
// string_starts_with(p->name, str_lit("main@")) ||
|
||||
false
|
||||
) { // IR Printing
|
||||
TB_Arena *arena = cg_arena();
|
||||
TB_Passes *passes = tb_pass_enter(p->func, arena);
|
||||
defer (tb_pass_exit(passes));
|
||||
// // emit ir
|
||||
// if (
|
||||
// // string_starts_with(p->name, str_lit("main@")) ||
|
||||
// false
|
||||
// ) { // IR Printing
|
||||
// TB_Arena *arena = cg_arena();
|
||||
// TB_Passes *passes = tb_pass_enter(p->func, arena);
|
||||
// defer (tb_pass_exit(passes));
|
||||
|
||||
tb_pass_print(passes);
|
||||
fprintf(stdout, "\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
if (false) { // GraphViz printing
|
||||
tb_pass_print_dot(opt, tb_default_print_callback, stdout);
|
||||
}
|
||||
// tb_pass_print(passes);
|
||||
// fprintf(stdout, "\n");
|
||||
// fflush(stdout);
|
||||
// }
|
||||
// if (false) { // GraphViz printing
|
||||
// tb_pass_print_dot(opt, tb_default_print_callback, stdout);
|
||||
// }
|
||||
|
||||
// compile
|
||||
TB_FunctionOutput *output = tb_pass_codegen(opt, emit_asm);
|
||||
if (emit_asm) {
|
||||
tb_output_print_asm(output, stdout);
|
||||
fprintf(stdout, "\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
// // compile
|
||||
// TB_FunctionOutput *output = tb_pass_codegen(opt, emit_asm);
|
||||
// if (emit_asm) {
|
||||
// tb_output_print_asm(output, stdout);
|
||||
// fprintf(stdout, "\n");
|
||||
// fflush(stdout);
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1025,8 +1026,8 @@ gb_internal cgProcedure *cg_equal_proc_for_type(cgModule *m, Type *type) {
|
||||
|
||||
TB_Node *x = tb_inst_param(p->func, 0);
|
||||
TB_Node *y = tb_inst_param(p->func, 1);
|
||||
GB_ASSERT(x->dt.type == TB_PTR);
|
||||
GB_ASSERT(y->dt.type == TB_PTR);
|
||||
GB_ASSERT(x->dt.type == TB_TAG_PTR);
|
||||
GB_ASSERT(y->dt.type == TB_TAG_PTR);
|
||||
|
||||
TB_DataType ret_dt = TB_PROTOTYPE_RETURNS(p->proto)->dt;
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_vol
|
||||
return cg_lvalue_addr(tb_inst_get_symbol_address(p->func, ptr.symbol), type);
|
||||
}
|
||||
}
|
||||
GB_ASSERT(dt.type != TB_MEMORY);
|
||||
GB_ASSERT(dt.type != TB_TUPLE);
|
||||
GB_ASSERT(dt.type != TB_TAG_MEMORY);
|
||||
GB_ASSERT(dt.type != TB_TAG_TUPLE);
|
||||
|
||||
// use the natural alignment
|
||||
// if people need a special alignment, they can use `intrinsics.unaligned_load`
|
||||
@@ -129,7 +129,7 @@ gb_internal void cg_emit_store(cgProcedure *p, cgValue dst, cgValue src, bool is
|
||||
case cgValue_Value:
|
||||
switch (src.kind) {
|
||||
case cgValue_Value:
|
||||
if (src.node->dt.type == TB_INT && src.node->dt.data == 1) {
|
||||
if (src.node->dt.type == TB_TAG_INT && src.node->dt.data == 1) {
|
||||
src.node = tb_inst_zxt(p->func, src.node, dt);
|
||||
}
|
||||
tb_inst_store(p->func, dt, dst.node, src.node, alignment, is_volatile);
|
||||
@@ -1178,7 +1178,7 @@ gb_internal void cg_build_return_stmt_internal(cgProcedure *p, Slice<cgValue> co
|
||||
GB_ASSERT(st.type == dt.type);
|
||||
if (st.raw == dt.raw) {
|
||||
final_res = result.node;
|
||||
} else if (st.type == TB_INT && st.data == 1) {
|
||||
} else if (st.type == TB_TAG_INT && st.data == 1) {
|
||||
final_res = tb_inst_zxt(p->func, result.node, dt);
|
||||
} else {
|
||||
final_res = tb_inst_bitcast(p->func, result.node, dt);
|
||||
@@ -1218,7 +1218,7 @@ gb_internal void cg_build_return_stmt_internal(cgProcedure *p, Slice<cgValue> co
|
||||
GB_ASSERT(st.type == dt.type);
|
||||
if (st.raw == dt.raw) {
|
||||
final_res = result.node;
|
||||
} else if (st.type == TB_INT && st.data == 1) {
|
||||
} else if (st.type == TB_TAG_INT && st.data == 1) {
|
||||
final_res = tb_inst_zxt(p->func, result.node, dt);
|
||||
} else {
|
||||
final_res = tb_inst_bitcast(p->func, result.node, dt);
|
||||
|
||||
Reference in New Issue
Block a user