|
@@ -349,9 +349,10 @@ gb_internal lbAddr lb_addr(lbValue addr) {
|
|
|
if (addr.type != nullptr && is_type_relative_pointer(type_deref(addr.type))) {
|
|
|
GB_ASSERT(is_type_pointer(addr.type));
|
|
|
v.kind = lbAddr_RelativePointer;
|
|
|
- } else if (addr.type != nullptr && is_type_relative_slice(type_deref(addr.type))) {
|
|
|
- GB_ASSERT(is_type_pointer(addr.type));
|
|
|
- v.kind = lbAddr_RelativeSlice;
|
|
|
+ } else if (addr.type != nullptr && is_type_relative_multi_pointer(type_deref(addr.type))) {
|
|
|
+ GB_ASSERT(is_type_pointer(addr.type) ||
|
|
|
+ is_type_multi_pointer(addr.type));
|
|
|
+ v.kind = lbAddr_RelativePointer;
|
|
|
}
|
|
|
return v;
|
|
|
}
|
|
@@ -424,6 +425,43 @@ gb_internal Type *lb_addr_type(lbAddr const &addr) {
|
|
|
return type_deref(addr.addr.type);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+gb_internal lbValue lb_relative_pointer_to_pointer(lbProcedure *p, lbAddr const &addr) {
|
|
|
+ GB_ASSERT(addr.kind == lbAddr_RelativePointer);
|
|
|
+
|
|
|
+ Type *t = base_type(lb_addr_type(addr));
|
|
|
+ GB_ASSERT(is_type_relative_pointer(t) || is_type_relative_multi_pointer(t));
|
|
|
+
|
|
|
+ Type *pointer_type = nullptr;
|
|
|
+ Type *base_integer = nullptr;
|
|
|
+ if (t->kind == Type_RelativePointer) {
|
|
|
+ pointer_type = t->RelativePointer.pointer_type;
|
|
|
+ base_integer = t->RelativePointer.base_integer;
|
|
|
+ } else if (t->kind == Type_RelativeMultiPointer) {
|
|
|
+ pointer_type = t->RelativeMultiPointer.pointer_type;
|
|
|
+ base_integer = t->RelativeMultiPointer.base_integer;
|
|
|
+ }
|
|
|
+
|
|
|
+ lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
|
|
|
+ lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(base_integer));
|
|
|
+ offset = lb_emit_load(p, offset);
|
|
|
+
|
|
|
+ if (!is_type_unsigned(base_integer)) {
|
|
|
+ offset = lb_emit_conv(p, offset, t_i64);
|
|
|
+ }
|
|
|
+ offset = lb_emit_conv(p, offset, t_uintptr);
|
|
|
+ lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
|
|
|
+ absolute_ptr = lb_emit_conv(p, absolute_ptr, pointer_type);
|
|
|
+
|
|
|
+ lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, base_integer));
|
|
|
+
|
|
|
+ // NOTE(bill): nil check
|
|
|
+ lbValue nil_ptr = lb_const_nil(p->module, pointer_type);
|
|
|
+ lbValue final_ptr = lb_emit_select(p, cond, nil_ptr, absolute_ptr);
|
|
|
+ return final_ptr;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
|
|
|
if (addr.addr.value == nullptr) {
|
|
|
GB_PANIC("Illegal addr -> nullptr");
|
|
@@ -434,28 +472,8 @@ gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
|
|
|
case lbAddr_Map:
|
|
|
return lb_internal_dynamic_map_get_ptr(p, addr.addr, addr.map.key);
|
|
|
|
|
|
- case lbAddr_RelativePointer: {
|
|
|
- Type *rel_ptr = base_type(lb_addr_type(addr));
|
|
|
- GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
|
|
|
-
|
|
|
- lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
|
|
|
- lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
|
|
|
- offset = lb_emit_load(p, offset);
|
|
|
-
|
|
|
- if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
|
|
|
- offset = lb_emit_conv(p, offset, t_i64);
|
|
|
- }
|
|
|
- offset = lb_emit_conv(p, offset, t_uintptr);
|
|
|
- lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
|
|
|
- absolute_ptr = lb_emit_conv(p, absolute_ptr, rel_ptr->RelativePointer.pointer_type);
|
|
|
-
|
|
|
- lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer));
|
|
|
-
|
|
|
- // NOTE(bill): nil check
|
|
|
- lbValue nil_ptr = lb_const_nil(p->module, rel_ptr->RelativePointer.pointer_type);
|
|
|
- lbValue final_ptr = lb_emit_select(p, cond, nil_ptr, absolute_ptr);
|
|
|
- return final_ptr;
|
|
|
- }
|
|
|
+ case lbAddr_RelativePointer:
|
|
|
+ return lb_relative_pointer_to_pointer(p, addr);
|
|
|
|
|
|
case lbAddr_SoaVariable:
|
|
|
// TODO(bill): FIX THIS HACK
|
|
@@ -477,6 +495,9 @@ gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
|
|
|
|
|
|
gb_internal lbValue lb_build_addr_ptr(lbProcedure *p, Ast *expr) {
|
|
|
lbAddr addr = lb_build_addr(p, expr);
|
|
|
+ if (addr.kind == lbAddr_RelativePointer) {
|
|
|
+ return addr.addr;
|
|
|
+ }
|
|
|
return lb_addr_get_ptr(p, addr);
|
|
|
}
|
|
|
|
|
@@ -685,9 +706,20 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
|
|
|
|
|
|
if (addr.kind == lbAddr_RelativePointer) {
|
|
|
Type *rel_ptr = base_type(lb_addr_type(addr));
|
|
|
- GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
|
|
|
+ GB_ASSERT(rel_ptr->kind == Type_RelativePointer ||
|
|
|
+ rel_ptr->kind == Type_RelativeMultiPointer);
|
|
|
+ Type *pointer_type = nullptr;
|
|
|
+ Type *base_integer = nullptr;
|
|
|
|
|
|
- value = lb_emit_conv(p, value, rel_ptr->RelativePointer.pointer_type);
|
|
|
+ if (rel_ptr->kind == Type_RelativePointer) {
|
|
|
+ pointer_type = rel_ptr->RelativePointer.pointer_type;
|
|
|
+ base_integer = rel_ptr->RelativePointer.base_integer;
|
|
|
+ } else if (rel_ptr->kind == Type_RelativeMultiPointer) {
|
|
|
+ pointer_type = rel_ptr->RelativeMultiPointer.pointer_type;
|
|
|
+ base_integer = rel_ptr->RelativeMultiPointer.base_integer;
|
|
|
+ }
|
|
|
+
|
|
|
+ value = lb_emit_conv(p, value, pointer_type);
|
|
|
|
|
|
GB_ASSERT(is_type_pointer(addr.addr.type));
|
|
|
lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
|
|
@@ -696,54 +728,20 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
|
|
|
offset.value = LLVMBuildSub(p->builder, val_ptr.value, ptr.value, "");
|
|
|
offset.type = t_uintptr;
|
|
|
|
|
|
- if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
|
|
|
+ if (!is_type_unsigned(base_integer)) {
|
|
|
offset = lb_emit_conv(p, offset, t_i64);
|
|
|
}
|
|
|
- offset = lb_emit_conv(p, offset, rel_ptr->RelativePointer.base_integer);
|
|
|
+ offset = lb_emit_conv(p, offset, base_integer);
|
|
|
|
|
|
- lbValue offset_ptr = lb_emit_conv(p, addr.addr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
|
|
|
+ lbValue offset_ptr = lb_emit_conv(p, addr.addr, alloc_type_pointer(base_integer));
|
|
|
offset = lb_emit_select(p,
|
|
|
lb_emit_comp(p, Token_CmpEq, val_ptr, lb_const_nil(p->module, t_uintptr)),
|
|
|
- lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer),
|
|
|
+ lb_const_nil(p->module, base_integer),
|
|
|
offset
|
|
|
);
|
|
|
LLVMBuildStore(p->builder, offset.value, offset_ptr.value);
|
|
|
return;
|
|
|
|
|
|
- } else if (addr.kind == lbAddr_RelativeSlice) {
|
|
|
- Type *rel_ptr = base_type(lb_addr_type(addr));
|
|
|
- GB_ASSERT(rel_ptr->kind == Type_RelativeSlice);
|
|
|
-
|
|
|
- value = lb_emit_conv(p, value, rel_ptr->RelativeSlice.slice_type);
|
|
|
-
|
|
|
- GB_ASSERT(is_type_pointer(addr.addr.type));
|
|
|
- lbValue ptr = lb_emit_conv(p, lb_emit_struct_ep(p, addr.addr, 0), t_uintptr);
|
|
|
- lbValue val_ptr = lb_emit_conv(p, lb_slice_elem(p, value), t_uintptr);
|
|
|
- lbValue offset = {};
|
|
|
- offset.value = LLVMBuildSub(p->builder, val_ptr.value, ptr.value, "");
|
|
|
- offset.type = t_uintptr;
|
|
|
-
|
|
|
- if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
|
|
|
- offset = lb_emit_conv(p, offset, t_i64);
|
|
|
- }
|
|
|
- offset = lb_emit_conv(p, offset, rel_ptr->RelativePointer.base_integer);
|
|
|
-
|
|
|
-
|
|
|
- lbValue offset_ptr = lb_emit_conv(p, addr.addr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
|
|
|
- offset = lb_emit_select(p,
|
|
|
- lb_emit_comp(p, Token_CmpEq, val_ptr, lb_const_nil(p->module, t_uintptr)),
|
|
|
- lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer),
|
|
|
- offset
|
|
|
- );
|
|
|
- LLVMBuildStore(p->builder, offset.value, offset_ptr.value);
|
|
|
-
|
|
|
- lbValue len = lb_slice_len(p, value);
|
|
|
- len = lb_emit_conv(p, len, rel_ptr->RelativePointer.base_integer);
|
|
|
-
|
|
|
- lbValue len_ptr = lb_emit_struct_ep(p, addr.addr, 1);
|
|
|
- LLVMBuildStore(p->builder, len.value, len_ptr.value);
|
|
|
-
|
|
|
- return;
|
|
|
} else if (addr.kind == lbAddr_Map) {
|
|
|
lb_internal_dynamic_map_set(p, addr.addr, addr.map.type, addr.map.key, value, p->curr_stmt);
|
|
|
return;
|
|
@@ -1020,67 +1018,43 @@ gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) {
|
|
|
|
|
|
if (addr.kind == lbAddr_RelativePointer) {
|
|
|
Type *rel_ptr = base_type(lb_addr_type(addr));
|
|
|
- GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
|
|
|
+ Type *base_integer = nullptr;
|
|
|
+ Type *pointer_type = nullptr;
|
|
|
+ GB_ASSERT(rel_ptr->kind == Type_RelativePointer ||
|
|
|
+ rel_ptr->kind == Type_RelativeMultiPointer);
|
|
|
+
|
|
|
+ if (rel_ptr->kind == Type_RelativePointer) {
|
|
|
+ base_integer = rel_ptr->RelativePointer.base_integer;
|
|
|
+ pointer_type = rel_ptr->RelativePointer.pointer_type;
|
|
|
+ } else if (rel_ptr->kind == Type_RelativeMultiPointer) {
|
|
|
+ base_integer = rel_ptr->RelativeMultiPointer.base_integer;
|
|
|
+ pointer_type = rel_ptr->RelativeMultiPointer.pointer_type;
|
|
|
+ }
|
|
|
|
|
|
lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
|
|
|
- lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
|
|
|
+ lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(base_integer));
|
|
|
offset = lb_emit_load(p, offset);
|
|
|
|
|
|
|
|
|
- if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
|
|
|
+ if (!is_type_unsigned(base_integer)) {
|
|
|
offset = lb_emit_conv(p, offset, t_i64);
|
|
|
}
|
|
|
offset = lb_emit_conv(p, offset, t_uintptr);
|
|
|
lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
|
|
|
- absolute_ptr = lb_emit_conv(p, absolute_ptr, rel_ptr->RelativePointer.pointer_type);
|
|
|
+ absolute_ptr = lb_emit_conv(p, absolute_ptr, pointer_type);
|
|
|
|
|
|
- lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer));
|
|
|
+ lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, base_integer));
|
|
|
|
|
|
// NOTE(bill): nil check
|
|
|
- lbValue nil_ptr = lb_const_nil(p->module, rel_ptr->RelativePointer.pointer_type);
|
|
|
+ lbValue nil_ptr = lb_const_nil(p->module, pointer_type);
|
|
|
lbValue final_ptr = {};
|
|
|
final_ptr.type = absolute_ptr.type;
|
|
|
final_ptr.value = LLVMBuildSelect(p->builder, cond.value, nil_ptr.value, absolute_ptr.value, "");
|
|
|
|
|
|
- return lb_emit_load(p, final_ptr);
|
|
|
-
|
|
|
- } else if (addr.kind == lbAddr_RelativeSlice) {
|
|
|
- Type *rel_ptr = base_type(lb_addr_type(addr));
|
|
|
- GB_ASSERT(rel_ptr->kind == Type_RelativeSlice);
|
|
|
-
|
|
|
- lbValue offset_ptr = lb_emit_struct_ep(p, addr.addr, 0);
|
|
|
- lbValue ptr = lb_emit_conv(p, offset_ptr, t_uintptr);
|
|
|
- lbValue offset = lb_emit_load(p, offset_ptr);
|
|
|
-
|
|
|
-
|
|
|
- if (!is_type_unsigned(rel_ptr->RelativeSlice.base_integer)) {
|
|
|
- offset = lb_emit_conv(p, offset, t_i64);
|
|
|
+ if (rel_ptr->kind == Type_RelativeMultiPointer) {
|
|
|
+ return final_ptr;
|
|
|
}
|
|
|
- offset = lb_emit_conv(p, offset, t_uintptr);
|
|
|
- lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
|
|
|
-
|
|
|
- Type *slice_type = base_type(rel_ptr->RelativeSlice.slice_type);
|
|
|
- GB_ASSERT(rel_ptr->RelativeSlice.slice_type->kind == Type_Slice);
|
|
|
- Type *slice_elem = slice_type->Slice.elem;
|
|
|
- Type *slice_elem_ptr = alloc_type_pointer(slice_elem);
|
|
|
-
|
|
|
- absolute_ptr = lb_emit_conv(p, absolute_ptr, slice_elem_ptr);
|
|
|
-
|
|
|
- lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativeSlice.base_integer));
|
|
|
-
|
|
|
- // NOTE(bill): nil check
|
|
|
- lbValue nil_ptr = lb_const_nil(p->module, slice_elem_ptr);
|
|
|
- lbValue data = {};
|
|
|
- data.type = absolute_ptr.type;
|
|
|
- data.value = LLVMBuildSelect(p->builder, cond.value, nil_ptr.value, absolute_ptr.value, "");
|
|
|
-
|
|
|
- lbValue len = lb_emit_load(p, lb_emit_struct_ep(p, addr.addr, 1));
|
|
|
- len = lb_emit_conv(p, len, t_int);
|
|
|
-
|
|
|
- lbAddr slice = lb_add_local_generated(p, slice_type, false);
|
|
|
- lb_fill_slice(p, slice, data, len);
|
|
|
- return lb_addr_load(p, slice);
|
|
|
-
|
|
|
+ return lb_emit_load(p, final_ptr);
|
|
|
|
|
|
} else if (addr.kind == lbAddr_Map) {
|
|
|
Type *map_type = base_type(type_deref(addr.addr.type));
|
|
@@ -2139,17 +2113,10 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
|
|
|
|
|
case Type_RelativePointer:
|
|
|
return lb_type_internal(m, type->RelativePointer.base_integer);
|
|
|
+ case Type_RelativeMultiPointer:
|
|
|
+ return lb_type_internal(m, type->RelativeMultiPointer.base_integer);
|
|
|
|
|
|
- case Type_RelativeSlice:
|
|
|
- {
|
|
|
- LLVMTypeRef base_integer = lb_type_internal(m, type->RelativeSlice.base_integer);
|
|
|
|
|
|
- unsigned field_count = 2;
|
|
|
- LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count);
|
|
|
- fields[0] = base_integer;
|
|
|
- fields[1] = base_integer;
|
|
|
- return LLVMStructTypeInContext(ctx, fields, field_count, false);
|
|
|
- }
|
|
|
|
|
|
case Type_Matrix:
|
|
|
{
|