diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-10-12 17:51:36 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-10-12 17:51:36 +0100 |
| commit | f3209584a3ae22afc84f2bde6899e248bc86a154 (patch) | |
| tree | 603caa5452dbd3b03ea0b7f6b3cf352f9ad640f4 /src/codegen | |
| parent | f5318c46d13ed3f3de20e0f61c4193e6ad46a42b (diff) | |
Add Pointer Arithmetic
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/codegen.cpp | 9 | ||||
| -rw-r--r-- | src/codegen/print_llvm.cpp | 27 | ||||
| -rw-r--r-- | src/codegen/ssa.cpp | 57 |
3 files changed, 72 insertions, 21 deletions
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index 6ca29902a..7d84a6c7b 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -377,6 +377,10 @@ void ssa_gen_tree(ssaGen *s) { case Basic_string: tag = ssa_add_local_generated(proc, t_type_info_string); break; + + case Basic_any: + tag = ssa_add_local_generated(proc, t_type_info_any); + break; } break; @@ -445,13 +449,12 @@ void ssa_gen_tree(ssaGen *s) { ssaValue *memory = type_info_member_offset(proc, type_info_member_data, t->Record.field_count, &type_info_member_index); type_set_offsets(m->sizes, a, t); // NOTE(bill): Just incase the offsets have not been set yet - for (isize i = 0; i < t->Record.field_count; i++) { + for (isize source_index = 0; source_index < t->Record.field_count; source_index++) { // TODO(bill): Order fields in source order not layout order - Entity *f = t->Record.fields_in_src_order[i]; + Entity *f = t->Record.fields_in_src_order[source_index]; ssaValue *tip = get_type_info_ptr(proc, type_info_data, f->type); i64 foffset = t->Record.struct_offsets[f->Variable.field_index]; GB_ASSERT(f->kind == Entity_Variable && f->Variable.field); - isize source_index = f->Variable.field_index; ssaValue *field = ssa_emit_ptr_offset(proc, memory, ssa_make_const_int(a, source_index)); ssaValue *name = ssa_emit_struct_gep(proc, field, v_zero32, t_string_ptr); diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 427407570..1c2e0929d 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -268,6 +268,16 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) { void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Type *type); void ssa_print_compound_element(ssaFileBuffer *f, ssaModule *m, ExactValue v, Type *elem_type) { + ssa_print_type(f, m, elem_type); + ssa_fprintf(f, " "); + + if (v.kind != ExactValue_Invalid && is_type_maybe(elem_type)) { + Type *t = base_type(elem_type)->Maybe.elem; + ssa_fprintf(f, "{"); + ssa_print_type(f, m, t); + ssa_fprintf(f, " "); + } + if (v.kind == ExactValue_Invalid) { ssa_fprintf(f, "zeroinitializer"); } else if (v.kind == ExactValue_String) { @@ -290,6 +300,13 @@ void ssa_print_compound_element(ssaFileBuffer *f, ssaModule *m, ExactValue v, Ty } else { ssa_print_exact_value(f, m, v, elem_type); } + + if (v.kind != ExactValue_Invalid && is_type_maybe(elem_type)) { + ssa_fprintf(f, ", "); + ssa_print_type(f, m, t_bool); + ssa_fprintf(f, " "); + ssa_fprintf(f, "true}"); + } } void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Type *type) { @@ -367,9 +384,6 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ if (i > 0) { ssa_fprintf(f, ", "); } - ssa_print_type(f, m, elem_type); - ssa_fprintf(f, " "); - TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[i]); GB_ASSERT(tav != NULL); ssa_print_compound_element(f, m, tav->value, elem_type); @@ -402,8 +416,6 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ if (i > 0) { ssa_fprintf(f, ", "); } - ssa_print_type(f, m, elem_type); - ssa_fprintf(f, " "); ssa_print_compound_element(f, m, tav->value, elem_type); } } else { @@ -411,9 +423,6 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ if (i > 0) { ssa_fprintf(f, ", "); } - ssa_print_type(f, m, elem_type); - ssa_fprintf(f, " "); - TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[i]); GB_ASSERT(tav != NULL); ssa_print_compound_element(f, m, tav->value, elem_type); @@ -476,8 +485,6 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ } Type *elem_type = type->Record.fields[i]->type; - ssa_print_type(f, m, elem_type); - ssa_fprintf(f, " "); ssa_print_compound_element(f, m, values[i], elem_type); } diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 3b6f7d8b7..9a4508aa2 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -1462,8 +1462,47 @@ void ssa_pop_target_list(ssaProcedure *proc) { } +ssaValue *ssa_emit_ptr_offset(ssaProcedure *proc, ssaValue *ptr, ssaValue *offset) { + ssaValue *gep = NULL; + offset = ssa_emit_conv(proc, offset, t_int); + gep = ssa_make_instr_get_element_ptr(proc, ptr, offset, NULL, 1, false); + gep->Instr.GetElementPtr.result_type = ssa_type(ptr); + return ssa_emit(proc, gep); +} ssaValue *ssa_emit_arith(ssaProcedure *proc, TokenKind op, ssaValue *left, ssaValue *right, Type *type) { + Type *t_left = ssa_type(left); + Type *t_right = ssa_type(right); + + if (op == Token_Add) { + if (is_type_pointer(t_left)) { + ssaValue *ptr = ssa_emit_conv(proc, left, type); + ssaValue *offset = right; + return ssa_emit_ptr_offset(proc, ptr, offset); + } else if (is_type_pointer(ssa_type(right))) { + ssaValue *ptr = ssa_emit_conv(proc, right, type); + ssaValue *offset = left; + return ssa_emit_ptr_offset(proc, ptr, offset); + } + } else if (op == Token_Sub) { + if (is_type_pointer(t_left) && is_type_integer(t_right)) { + // ptr - int + ssaValue *ptr = ssa_emit_conv(proc, left, type); + ssaValue *offset = right; + return ssa_emit_ptr_offset(proc, ptr, offset); + } else if (is_type_pointer(t_left) && is_type_pointer(t_right)) { + GB_ASSERT(is_type_integer(type)); + Type *ptr_type = t_left; + ssaModule *m = proc->module; + ssaValue *x = ssa_emit_conv(proc, left, type); + ssaValue *y = ssa_emit_conv(proc, right, type); + ssaValue *diff = ssa_emit_arith(proc, op, x, y, type); + ssaValue *elem_size = ssa_make_const_int(m->allocator, type_size_of(m->sizes, m->allocator, ptr_type)); + return ssa_emit_arith(proc, Token_Quo, diff, elem_size, type); + } + } + + switch (op) { case Token_AndNot: { // NOTE(bill): x &~ y == x & (~y) == x & (y ~ -1) @@ -1510,13 +1549,7 @@ ssaValue *ssa_emit_comp(ssaProcedure *proc, TokenKind op_kind, ssaValue *left, s return ssa_emit(proc, ssa_make_instr_binary_op(proc, op_kind, left, right, result)); } -ssaValue *ssa_emit_ptr_offset(ssaProcedure *proc, ssaValue *ptr, ssaValue *offset) { - ssaValue *gep = NULL; - offset = ssa_emit_conv(proc, offset, t_int); - gep = ssa_make_instr_get_element_ptr(proc, ptr, offset, NULL, 1, false); - gep->Instr.GetElementPtr.result_type = ssa_type(ptr); - return ssa_emit(proc, gep); -} + ssaValue *ssa_emit_zero_gep(ssaProcedure *proc, ssaValue *s) { ssaValue *gep = NULL; @@ -2824,6 +2857,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue } break; +#if 0 case BuiltinProc_ptr_offset: { ssa_emit_comment(proc, make_string("ptr_offset")); ssaValue *ptr = ssa_build_expr(proc, ce->args[0]); @@ -2847,6 +2881,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue return v; } break; +#endif case BuiltinProc_slice_ptr: { ssa_emit_comment(proc, make_string("slice_ptr")); @@ -3440,7 +3475,13 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) { void ssa_build_assign_op(ssaProcedure *proc, ssaAddr lhs, ssaValue *value, TokenKind op) { ssaValue *old_value = ssa_lvalue_load(proc, lhs); Type *type = ssa_type(old_value); - ssaValue *change = ssa_emit_conv(proc, value, type); + + ssaValue *change = value; + if (is_type_pointer(type) && is_type_integer(ssa_type(value))) { + change = ssa_emit_conv(proc, value, default_type(ssa_type(value))); + } else { + change = ssa_emit_conv(proc, value, type); + } ssaValue *new_value = ssa_emit_arith(proc, op, old_value, change, type); ssa_lvalue_store(proc, lhs, new_value); } |