aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2020-05-15 17:52:09 +0100
committergingerBill <bill@gingerbill.org>2020-05-15 17:52:09 +0100
commit95e8668b779ec59d9e0a3afefb51d599c6602cd2 (patch)
treef594fd75d24456604aab39937316b2721990d514 /src/ir.cpp
parent90adf214d7d96a5f9f9dc7d558ed4b3208a518f5 (diff)
Relative pointers in old backend
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp104
1 files changed, 89 insertions, 15 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 2036c94ab..ee4c03fc5 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -493,6 +493,7 @@ enum irAddrKind {
irAddr_BitField,
irAddr_Context,
irAddr_SoaVariable,
+ irAddr_RelativePointer,
};
struct irAddr {
@@ -517,8 +518,14 @@ struct irAddr {
};
};
+Type *ir_type(irValue *value);
+
irAddr ir_addr(irValue *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;
}
@@ -722,7 +729,6 @@ gb_inline bool ir_min_dep_entity(irModule *m, Entity *e) {
return ptr_set_exists(&m->min_dep_set, e);
}
-Type *ir_type(irValue *value);
Type *ir_instr_type(irInstr *instr) {
switch (instr->kind) {
case irInstr_Local:
@@ -772,6 +778,9 @@ Type *ir_instr_type(irInstr *instr) {
}
Type *ir_type(irValue *value) {
+ if (value == nullptr) {
+ return nullptr;
+ }
switch (value->kind) {
case irValue_Constant:
return value->Constant.type;
@@ -3626,7 +3635,27 @@ void ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) {
if (addr.addr == nullptr) {
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);
return;
} else if (addr.kind == irAddr_BitField) {
@@ -3770,7 +3799,31 @@ irValue *ir_addr_load(irProcedure *proc, irAddr const &addr) {
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);
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);
@@ -6004,19 +6057,22 @@ irValue *ir_typeid(irModule *m, Type *type) {
if (flags & BasicFlag_String) kind = Typeid_String;
if (flags & BasicFlag_Rune) kind = Typeid_Rune;
} break;
- case Type_Pointer: kind = Typeid_Pointer; break;
- case Type_Array: kind = Typeid_Array; break;
+ case Type_Pointer: kind = Typeid_Pointer; break;
+ case Type_Array: kind = Typeid_Array; break;
case Type_EnumeratedArray: kind = Typeid_Enumerated_Array; break;
- case Type_Slice: kind = Typeid_Slice; break;
- case Type_DynamicArray: kind = Typeid_Dynamic_Array; break;
- case Type_Map: kind = Typeid_Map; break;
- case Type_Struct: kind = Typeid_Struct; break;
- case Type_Enum: kind = Typeid_Enum; break;
- case Type_Union: kind = Typeid_Union; break;
- case Type_Tuple: kind = Typeid_Tuple; break;
- case Type_Proc: kind = Typeid_Procedure; break;
- case Type_BitField: kind = Typeid_Bit_Field; break;
- case Type_BitSet: kind = Typeid_Bit_Set; break;
+ case Type_Slice: kind = Typeid_Slice; break;
+ case Type_DynamicArray: kind = Typeid_Dynamic_Array; break;
+ case Type_Map: kind = Typeid_Map; break;
+ case Type_Struct: kind = Typeid_Struct; break;
+ case Type_Enum: kind = Typeid_Enum; break;
+ case Type_Union: kind = Typeid_Union; break;
+ case Type_Tuple: kind = Typeid_Tuple; break;
+ case Type_Proc: kind = Typeid_Procedure; break;
+ case Type_BitField: kind = Typeid_Bit_Field; 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)) {
@@ -8476,6 +8532,10 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) {
case_end;
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?
irValue *addr = ir_build_expr(proc, de->expr);
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));
}
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;
}