diff options
| author | gingerBill <bill+github@gingerbill.org> | 2016-08-10 11:53:17 +0100 |
|---|---|---|
| committer | gingerBill <bill+github@gingerbill.org> | 2016-08-10 11:53:17 +0100 |
| commit | 153c27c7556ebef0c98055d87937b942d198f629 (patch) | |
| tree | bdb5b61a78e4eed8f232a808a74fad480330529e /src/codegen | |
| parent | c930841f834e43df28be41e8e3509773a523ed0f (diff) | |
Tuple support in codegen
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/codegen.cpp | 2 | ||||
| -rw-r--r-- | src/codegen/print_llvm.cpp | 7 | ||||
| -rw-r--r-- | src/codegen/ssa.cpp | 90 |
3 files changed, 89 insertions, 10 deletions
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index 420be8ede..7af2c01cd 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -81,6 +81,8 @@ void ssa_gen_code(ssaGen *s) { ssa_build_proc(v); } + // m->layout = make_string("e-p:64:64:64"); + ssa_print_llvm_ir(&s->output_file, &s->module); } diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 55b03d5ca..d4765ceb7 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -129,6 +129,9 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) { ssa_fprintf(f, "*, i%lld, i%lld}", word_bits, word_bits); break; case Type_Structure: + if (t->structure.is_packed) { + ssa_fprintf(f, "<"); + } ssa_fprintf(f, "{"); for (isize i = 0; i < t->structure.field_count; i++) { if (i > 0) { @@ -137,6 +140,10 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) { ssa_print_type(f, s, t->structure.fields[i]->type); } ssa_fprintf(f, "}"); + if (t->structure.is_packed) { + ssa_fprintf(f, ">"); + } + break; case Type_Pointer: ssa_print_type(f, s, t->pointer.elem); diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 57887d3f1..972f8dc72 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -1244,6 +1244,11 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue GB_PANIC("TODO(bill): ssa_build_single_expr ProcLit"); case_end; + + case_ast_node(pl, CompoundLit, expr); + GB_PANIC("TODO(bill): ssa_build_single_expr CompoundLit"); + case_end; + case_ast_node(ce, CastExpr, expr); return ssa_emit_conv(proc, ssa_build_expr(proc, ce->expr), tv->type); case_end; @@ -1305,19 +1310,20 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue ssaValue *a = ssa_build_expr(proc, arg); Type *at = ssa_value_type(a); if (at->kind == Type_Tuple) { - GB_PANIC("TODO(bill): tuple call arguments"); + ssaValue *tuple = ssa_add_local_generated(proc, at); + ssa_emit_store(proc, tuple, a); + for (isize i = 0; i < at->tuple.variable_count; i++) { + Entity *e = at->tuple.variables[i]; + ssaValue *index = ssa_make_value_constant(proc->module->allocator, t_i32, make_exact_value_integer(i)); + ssaValue *v = ssa_emit_struct_gep(proc, tuple, index, e->type); + v = ssa_emit_load(proc, v); + args[arg_index++] = v; + } } else { args[arg_index++] = a; } } -#if 0 - for (isize i = 0; i < arg_count; i++) { - Entity *e = type->params->tuple.variables[i]; - args[i] = ssa_emit_conv(proc, args[i], e->type); - } -#endif - ssaValue *call = ssa_make_instr_call(proc, value, args, arg_count, tv->type); ssa_value_set_type(call, proc_type_); return ssa_emit(proc, call); @@ -1569,7 +1575,46 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { } } } else { // Tuple(s) - GB_PANIC("TODO(bill): tuple assignment variable declaration"); + gbArray(ssaLvalue) lvals; + gbArray(ssaValue *) inits; + gb_array_init_reserve(lvals, gb_heap_allocator(), vd->name_count); + gb_array_init_reserve(inits, gb_heap_allocator(), vd->name_count); + defer (gb_array_free(lvals)); + defer (gb_array_free(inits)); + + for (AstNode *name = vd->name_list; name != NULL; name = name->next) { + ssaLvalue lval = {ssaLvalue_Blank}; + if (!ssa_is_blank_ident(name)) { + ssa_add_local_for_identifier(proc, name); + lval = ssa_build_addr(proc, name); + } + + gb_array_append(lvals, lval); + } + + for (AstNode *value = vd->value_list; value != NULL; value = value->next) { + ssaValue *init = ssa_build_expr(proc, value); + Type *t = ssa_value_type(init); + if (t->kind == Type_Tuple) { + ssaValue *tuple = ssa_add_local_generated(proc, t); + ssa_emit_store(proc, tuple, init); + for (isize i = 0; i < t->tuple.variable_count; i++) { + Entity *e = t->tuple.variables[i]; + ssaValue *index = ssa_make_value_constant(proc->module->allocator, t_i32, make_exact_value_integer(i)); + ssaValue *v = ssa_emit_struct_gep(proc, tuple, index, e->type); + v = ssa_emit_load(proc, v); + gb_array_append(inits, v); + } + } else { + gb_array_append(inits, init); + } + } + + + gb_for_array(i, inits) { + ssaValue *v = ssa_emit_conv(proc, inits[i], ssa_lvalue_type(lvals[i])); + ssa_lvalue_store(lvals[i], proc, v); + } } } case_end; @@ -1624,7 +1669,32 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { } } } else { - GB_PANIC("TODO(bill): tuple assignment"); + gbArray(ssaValue *) inits; + gb_array_init_reserve(inits, gb_heap_allocator(), gb_array_count(lvals)); + defer (gb_array_free(inits)); + + for (AstNode *rhs = as->rhs_list; rhs != NULL; rhs = rhs->next) { + ssaValue *init = ssa_build_expr(proc, rhs); + Type *t = ssa_value_type(init); + // TODO(bill): refactor for code reuse as this is repeated a bit + if (t->kind == Type_Tuple) { + ssaValue *tuple = ssa_add_local_generated(proc, t); + ssa_emit_store(proc, tuple, init); + for (isize i = 0; i < t->tuple.variable_count; i++) { + Entity *e = t->tuple.variables[i]; + ssaValue *index = ssa_make_value_constant(proc->module->allocator, t_i32, make_exact_value_integer(i)); + ssaValue *v = ssa_emit_struct_gep(proc, tuple, index, e->type); + v = ssa_emit_load(proc, v); + gb_array_append(inits, v); + } + } else { + gb_array_append(inits, init); + } + } + + gb_for_array(i, inits) { + ssa_lvalue_store(lvals[i], proc, inits[i]); + } } } break; |