mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-03 11:42:28 +00:00
cg_emit_load/cg_emit_store
This commit is contained in:
@@ -1,5 +1,88 @@
|
||||
#include "tilde_backend.hpp"
|
||||
|
||||
// returns TB_TYPE_VOID if not trivially possible
|
||||
gb_internal TB_DataType cg_data_type(Type *t) {
|
||||
GB_ASSERT(t != nullptr);
|
||||
t = core_type(t);
|
||||
switch (t->kind) {
|
||||
case Type_Basic:
|
||||
switch (t->Basic.kind) {
|
||||
case Basic_bool: return TB_TYPE_BOOL;
|
||||
case Basic_b8: return TB_TYPE_BOOL;
|
||||
case Basic_b16: return TB_TYPE_I16;
|
||||
case Basic_b32: return TB_TYPE_I32;
|
||||
case Basic_b64: return TB_TYPE_I64;
|
||||
|
||||
case Basic_i8: return TB_TYPE_I8;
|
||||
case Basic_u8: return TB_TYPE_I8;
|
||||
case Basic_i16: return TB_TYPE_I16;
|
||||
case Basic_u16: return TB_TYPE_I16;
|
||||
case Basic_i32: return TB_TYPE_I32;
|
||||
case Basic_u32: return TB_TYPE_I32;
|
||||
case Basic_i64: return TB_TYPE_I64;
|
||||
case Basic_u64: return TB_TYPE_I64;
|
||||
case Basic_i128: return TB_TYPE_I128;
|
||||
case Basic_u128: return TB_TYPE_I128;
|
||||
|
||||
case Basic_rune: return TB_TYPE_I32;
|
||||
|
||||
case Basic_f16: return TB_TYPE_I16;
|
||||
case Basic_f32: return TB_TYPE_F32;
|
||||
case Basic_f64: return TB_TYPE_F64;
|
||||
|
||||
case Basic_int: return TB_TYPE_INTN(cast(u16)build_context.int_size);
|
||||
case Basic_uint: return TB_TYPE_INTN(cast(u16)build_context.int_size);
|
||||
case Basic_uintptr: return TB_TYPE_INTN(cast(u16)build_context.ptr_size);
|
||||
case Basic_rawptr: return TB_TYPE_PTR;
|
||||
case Basic_cstring: return TB_TYPE_PTR;
|
||||
|
||||
case Basic_typeid: return TB_TYPE_INTN(cast(u16)build_context.ptr_size);
|
||||
|
||||
// Endian Specific Types
|
||||
case Basic_i16le: return TB_TYPE_I16;
|
||||
case Basic_u16le: return TB_TYPE_I16;
|
||||
case Basic_i32le: return TB_TYPE_I32;
|
||||
case Basic_u32le: return TB_TYPE_I32;
|
||||
case Basic_i64le: return TB_TYPE_I64;
|
||||
case Basic_u64le: return TB_TYPE_I64;
|
||||
case Basic_i128le: return TB_TYPE_I128;
|
||||
case Basic_u128le: return TB_TYPE_I128;
|
||||
|
||||
case Basic_i16be: return TB_TYPE_I16;
|
||||
case Basic_u16be: return TB_TYPE_I16;
|
||||
case Basic_i32be: return TB_TYPE_I32;
|
||||
case Basic_u32be: return TB_TYPE_I32;
|
||||
case Basic_i64be: return TB_TYPE_I64;
|
||||
case Basic_u64be: return TB_TYPE_I64;
|
||||
case Basic_i128be: return TB_TYPE_I128;
|
||||
case Basic_u128be: return TB_TYPE_I128;
|
||||
|
||||
case Basic_f16le: return TB_TYPE_I16;
|
||||
case Basic_f32le: return TB_TYPE_F32;
|
||||
case Basic_f64le: return TB_TYPE_F64;
|
||||
|
||||
case Basic_f16be: return TB_TYPE_I16;
|
||||
case Basic_f32be: return TB_TYPE_F32;
|
||||
case Basic_f64be: return TB_TYPE_F64;
|
||||
}
|
||||
|
||||
case Type_Pointer:
|
||||
case Type_MultiPointer:
|
||||
case Type_Proc:
|
||||
return TB_TYPE_PTR;
|
||||
|
||||
case Type_BitSet:
|
||||
return cg_data_type(bit_set_to_int(t));
|
||||
|
||||
case Type_RelativePointer:
|
||||
return cg_data_type(t->RelativePointer.base_integer);
|
||||
}
|
||||
|
||||
// unknown
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
gb_internal cgValue cg_value(TB_Global *g, Type *type) {
|
||||
return cg_value((TB_Symbol *)g, type);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
#include "tilde/tb.h"
|
||||
|
||||
#define TB_TYPE_I128 TB_DataType{ { TB_INT, 0, 128 } }
|
||||
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
@@ -50,6 +50,10 @@ gb_internal cgValue cg_build_expr(cgProcedure *p, Ast *expr) {
|
||||
}
|
||||
|
||||
cgValue res = cg_build_expr_internal(p, expr);
|
||||
if (res.kind == cgValue_Symbol) {
|
||||
GB_ASSERT(is_type_pointer(res.type));
|
||||
res = cg_value(tb_inst_get_symbol_address(p->func, res.symbol), res.type);
|
||||
}
|
||||
|
||||
if (expr->state_flags & StateFlag_SelectorCallExpr) {
|
||||
// map_set(&p->selector_values, expr, res);
|
||||
|
||||
@@ -96,6 +96,90 @@ gb_internal void cg_build_assignment(cgProcedure *p, Array<cgAddr> const &lhs, S
|
||||
}
|
||||
|
||||
|
||||
gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_volatile=false) {
|
||||
GB_ASSERT(is_type_pointer(ptr.type));
|
||||
Type *type = type_deref(ptr.type);
|
||||
TB_DataType dt = cg_data_type(type);
|
||||
|
||||
if (TB_IS_VOID_TYPE(dt)) {
|
||||
switch (ptr.kind) {
|
||||
case cgValue_Value:
|
||||
return cg_lvalue_addr(ptr.node, type);
|
||||
case cgValue_Addr:
|
||||
GB_PANIC("NOT POSSIBLE");
|
||||
break;
|
||||
case cgValue_Symbol:
|
||||
return cg_lvalue_addr(tb_inst_get_symbol_address(p->func, ptr.symbol), type);
|
||||
}
|
||||
}
|
||||
|
||||
TB_CharUnits alignment = 1; // for the time being
|
||||
|
||||
TB_Node *the_ptr = nullptr;
|
||||
switch (ptr.kind) {
|
||||
case cgValue_Value:
|
||||
the_ptr = ptr.node;
|
||||
break;
|
||||
case cgValue_Addr:
|
||||
the_ptr = tb_inst_load(p->func, TB_TYPE_PTR, ptr.node, alignment, is_volatile);
|
||||
break;
|
||||
case cgValue_Symbol:
|
||||
the_ptr = tb_inst_get_symbol_address(p->func, ptr.symbol);
|
||||
break;
|
||||
}
|
||||
return cg_value(tb_inst_load(p->func, dt, the_ptr, alignment, is_volatile), type);
|
||||
}
|
||||
|
||||
gb_internal void cg_emit_store(cgProcedure *p, cgValue dst, cgValue const &src, bool is_volatile=false) {
|
||||
if (dst.kind == cgValue_Addr) {
|
||||
dst = cg_emit_load(p, dst, is_volatile);
|
||||
} else if (dst.kind = cgValue_Symbol) {
|
||||
dst = cg_value(tb_inst_get_symbol_address(p->func, dst.symbol), dst.type);
|
||||
}
|
||||
|
||||
GB_ASSERT(is_type_pointer(dst.type));
|
||||
Type *dst_type = type_deref(dst.type);
|
||||
|
||||
GB_ASSERT_MSG(are_types_identical(dst_type, src.type), "%s vs %s", type_to_string(dst_type), type_to_string(src.type));
|
||||
|
||||
TB_DataType dt = cg_data_type(dst_type);
|
||||
TB_DataType st = cg_data_type(src.type);
|
||||
GB_ASSERT(dt.raw == st.raw);
|
||||
|
||||
if (TB_IS_VOID_TYPE(dt)) {
|
||||
// TODO(bill): needs to be memmove
|
||||
GB_PANIC("todo emit store to aggregate type");
|
||||
return;
|
||||
}
|
||||
|
||||
TB_CharUnits alignment = 1; // for the time being
|
||||
|
||||
switch (dst.kind) {
|
||||
case cgValue_Value:
|
||||
switch (dst.kind) {
|
||||
case cgValue_Value:
|
||||
tb_inst_store(p->func, dt, dst.node, src.node, alignment, is_volatile);
|
||||
return;
|
||||
case cgValue_Addr:
|
||||
tb_inst_store(p->func, dt, dst.node,
|
||||
tb_inst_load(p->func, st, src.node, alignment, is_volatile),
|
||||
alignment, is_volatile);
|
||||
return;
|
||||
case cgValue_Symbol:
|
||||
tb_inst_store(p->func, dt, dst.node,
|
||||
tb_inst_get_symbol_address(p->func, src.symbol),
|
||||
alignment, is_volatile);
|
||||
return;
|
||||
}
|
||||
case cgValue_Addr:
|
||||
case cgValue_Symbol:
|
||||
GB_PANIC("should be handled above");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
gb_internal void cg_build_assign_stmt(cgProcedure *p, AstAssignStmt *as) {
|
||||
if (as->op.kind == Token_Eq) {
|
||||
auto lvals = array_make<cgAddr>(permanent_allocator(), 0, as->lhs.count);
|
||||
|
||||
Reference in New Issue
Block a user