mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Relative pointers in old backend
This commit is contained in:
+77
-3
@@ -493,6 +493,7 @@ enum irAddrKind {
|
|||||||
irAddr_BitField,
|
irAddr_BitField,
|
||||||
irAddr_Context,
|
irAddr_Context,
|
||||||
irAddr_SoaVariable,
|
irAddr_SoaVariable,
|
||||||
|
irAddr_RelativePointer,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct irAddr {
|
struct irAddr {
|
||||||
@@ -517,8 +518,14 @@ struct irAddr {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Type *ir_type(irValue *value);
|
||||||
|
|
||||||
irAddr ir_addr(irValue *addr) {
|
irAddr ir_addr(irValue *addr) {
|
||||||
irAddr v = {irAddr_Default, addr};
|
irAddr v = {irAddr_Default, addr};
|
||||||
|
if (addr != nullptr && is_type_relative_pointer(type_deref(ir_type(addr)))) {
|
||||||
|
GB_ASSERT(is_type_pointer(ir_type(addr)));
|
||||||
|
v.kind = irAddr_RelativePointer;
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -722,7 +729,6 @@ gb_inline bool ir_min_dep_entity(irModule *m, Entity *e) {
|
|||||||
return ptr_set_exists(&m->min_dep_set, e);
|
return ptr_set_exists(&m->min_dep_set, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type *ir_type(irValue *value);
|
|
||||||
Type *ir_instr_type(irInstr *instr) {
|
Type *ir_instr_type(irInstr *instr) {
|
||||||
switch (instr->kind) {
|
switch (instr->kind) {
|
||||||
case irInstr_Local:
|
case irInstr_Local:
|
||||||
@@ -772,6 +778,9 @@ Type *ir_instr_type(irInstr *instr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type *ir_type(irValue *value) {
|
Type *ir_type(irValue *value) {
|
||||||
|
if (value == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
switch (value->kind) {
|
switch (value->kind) {
|
||||||
case irValue_Constant:
|
case irValue_Constant:
|
||||||
return value->Constant.type;
|
return value->Constant.type;
|
||||||
@@ -3626,7 +3635,27 @@ void ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) {
|
|||||||
if (addr.addr == nullptr) {
|
if (addr.addr == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (addr.kind == irAddr_Map) {
|
if (addr.kind == irAddr_RelativePointer) {
|
||||||
|
Type *rel_ptr = base_type(ir_addr_type(addr));
|
||||||
|
GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
|
||||||
|
|
||||||
|
value = ir_emit_conv(proc, value, rel_ptr->RelativePointer.pointer_type);
|
||||||
|
|
||||||
|
GB_ASSERT(is_type_pointer(ir_type(addr.addr)));
|
||||||
|
irValue *ptr = ir_emit_conv(proc, addr.addr, t_uintptr);
|
||||||
|
irValue *val_ptr = ir_emit_conv(proc, value, t_uintptr);
|
||||||
|
irValue *offset = offset = ir_emit_arith(proc, Token_Sub, val_ptr, ptr, t_uintptr);
|
||||||
|
|
||||||
|
if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
|
||||||
|
offset = ir_emit_conv(proc, offset, t_i64);
|
||||||
|
}
|
||||||
|
offset = ir_emit_conv(proc, offset, rel_ptr->RelativePointer.base_integer);
|
||||||
|
|
||||||
|
irValue *offset_ptr = ir_emit_conv(proc, addr.addr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
|
||||||
|
ir_emit_store(proc, offset_ptr, offset);
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if (addr.kind == irAddr_Map) {
|
||||||
ir_insert_dynamic_map_key_and_value(proc, addr.addr, addr.map_type, addr.map_key, value);
|
ir_insert_dynamic_map_key_and_value(proc, addr.addr, addr.map_type, addr.map_key, value);
|
||||||
return;
|
return;
|
||||||
} else if (addr.kind == irAddr_BitField) {
|
} else if (addr.kind == irAddr_BitField) {
|
||||||
@@ -3770,7 +3799,31 @@ irValue *ir_addr_load(irProcedure *proc, irAddr const &addr) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr.kind == irAddr_Map) {
|
if (addr.kind == irAddr_RelativePointer) {
|
||||||
|
Type *rel_ptr = base_type(ir_addr_type(addr));
|
||||||
|
GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
|
||||||
|
|
||||||
|
irValue *ptr = ir_emit_conv(proc, addr.addr, t_uintptr);
|
||||||
|
irValue *offset = ir_emit_conv(proc, ptr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
|
||||||
|
offset = ir_emit_load(proc, offset);
|
||||||
|
|
||||||
|
|
||||||
|
if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
|
||||||
|
offset = ir_emit_conv(proc, offset, t_i64);
|
||||||
|
}
|
||||||
|
offset = ir_emit_conv(proc, offset, t_uintptr);
|
||||||
|
irValue *absolute_ptr = ir_emit_arith(proc, Token_Add, ptr, offset, t_uintptr);
|
||||||
|
absolute_ptr = ir_emit_conv(proc, absolute_ptr, rel_ptr->RelativePointer.pointer_type);
|
||||||
|
|
||||||
|
irValue *cond = ir_emit_comp(proc, Token_CmpEq, offset, ir_value_nil(rel_ptr->RelativePointer.base_integer));
|
||||||
|
|
||||||
|
// NOTE(bill): nil check
|
||||||
|
irValue *nil_ptr = ir_value_nil(rel_ptr->RelativePointer.pointer_type);
|
||||||
|
irValue *final_ptr = ir_emit_select(proc, cond, nil_ptr, absolute_ptr);
|
||||||
|
|
||||||
|
return ir_emit_load(proc, final_ptr);
|
||||||
|
|
||||||
|
} else if (addr.kind == irAddr_Map) {
|
||||||
Type *map_type = base_type(addr.map_type);
|
Type *map_type = base_type(addr.map_type);
|
||||||
irValue *v = ir_add_local_generated(proc, map_type->Map.lookup_result_type, true);
|
irValue *v = ir_add_local_generated(proc, map_type->Map.lookup_result_type, true);
|
||||||
irValue *h = ir_gen_map_header(proc, addr.addr, map_type);
|
irValue *h = ir_gen_map_header(proc, addr.addr, map_type);
|
||||||
@@ -6017,6 +6070,9 @@ irValue *ir_typeid(irModule *m, Type *type) {
|
|||||||
case Type_Proc: kind = Typeid_Procedure; break;
|
case Type_Proc: kind = Typeid_Procedure; break;
|
||||||
case Type_BitField: kind = Typeid_Bit_Field; break;
|
case Type_BitField: kind = Typeid_Bit_Field; break;
|
||||||
case Type_BitSet: kind = Typeid_Bit_Set; break;
|
case Type_BitSet: kind = Typeid_Bit_Set; break;
|
||||||
|
case Type_SimdVector: kind = Typeid_Simd_Vector; break;
|
||||||
|
case Type_RelativePointer: kind = Typeid_Relative_Pointer; break;
|
||||||
|
case Type_RelativeSlice: kind = Typeid_Relative_Slice; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_type_cstring(type)) {
|
if (is_type_cstring(type)) {
|
||||||
@@ -8476,6 +8532,10 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) {
|
|||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(de, DerefExpr, expr);
|
case_ast_node(de, DerefExpr, expr);
|
||||||
|
if (is_type_relative_pointer(type_of_expr(de->expr))) {
|
||||||
|
return ir_build_addr(proc, de->expr);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(bill): Is a ptr copy needed?
|
// TODO(bill): Is a ptr copy needed?
|
||||||
irValue *addr = ir_build_expr(proc, de->expr);
|
irValue *addr = ir_build_expr(proc, de->expr);
|
||||||
addr = ir_emit_ptr_offset(proc, addr, v_zero);
|
addr = ir_emit_ptr_offset(proc, addr, v_zero);
|
||||||
@@ -11935,6 +11995,20 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
|||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), ir_const_int(t->SimdVector.count));
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), ir_const_int(t->SimdVector.count));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Type_RelativePointer:
|
||||||
|
ir_emit_comment(proc, str_lit("Type_RelativePointer"));
|
||||||
|
tag = ir_emit_conv(proc, variant_ptr, t_type_info_relative_pointer_ptr);
|
||||||
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), ir_get_type_info_ptr(proc, t->RelativePointer.pointer_type));
|
||||||
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), ir_get_type_info_ptr(proc, t->RelativePointer.base_integer));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type_RelativeSlice:
|
||||||
|
ir_emit_comment(proc, str_lit("Type_RelativeSlice"));
|
||||||
|
tag = ir_emit_conv(proc, variant_ptr, t_type_info_relative_slice_ptr);
|
||||||
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), ir_get_type_info_ptr(proc, t->RelativePointer.pointer_type));
|
||||||
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), ir_get_type_info_ptr(proc, t->RelativePointer.base_integer));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -669,6 +669,18 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) {
|
|||||||
ir_write_byte(f, '>');
|
ir_write_byte(f, '>');
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case Type_RelativePointer:
|
||||||
|
ir_print_type(f, m, t->RelativePointer.base_integer);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Type_RelativeSlice:
|
||||||
|
ir_write_byte(f, '{');
|
||||||
|
ir_print_type(f, m, t->RelativePointer.base_integer);
|
||||||
|
ir_write_str_lit(f, ", ");
|
||||||
|
ir_print_type(f, m, t->RelativePointer.base_integer);
|
||||||
|
ir_write_byte(f, '}');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ LLVMValueRef llvm_cstring(lbModule *m, String const &str) {
|
|||||||
|
|
||||||
lbAddr lb_addr(lbValue addr) {
|
lbAddr lb_addr(lbValue addr) {
|
||||||
lbAddr v = {lbAddr_Default, addr};
|
lbAddr v = {lbAddr_Default, addr};
|
||||||
if (is_type_relative_pointer(type_deref(addr.type))) {
|
if (addr.type != nullptr && is_type_relative_pointer(type_deref(addr.type))) {
|
||||||
GB_ASSERT(is_type_pointer(addr.type));
|
GB_ASSERT(is_type_pointer(addr.type));
|
||||||
v.kind = lbAddr_RelativePointer;
|
v.kind = lbAddr_RelativePointer;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user