diff options
| author | gingerBill <bill+github@gingerbill.org> | 2016-08-10 10:00:57 +0100 |
|---|---|---|
| committer | gingerBill <bill+github@gingerbill.org> | 2016-08-10 10:00:57 +0100 |
| commit | c930841f834e43df28be41e8e3509773a523ed0f (patch) | |
| tree | f4de597e6028c64a7454ff116652f80c0d58ba34 /src/codegen | |
| parent | cff5e54ec6b8d9b95effcad1ca2dd8bb0988517b (diff) | |
f16/f128,u|i128, basic vector support.
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/print_llvm.cpp | 41 | ||||
| -rw-r--r-- | src/codegen/ssa.cpp | 53 |
2 files changed, 72 insertions, 22 deletions
diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 5ae423f41..55b03d5ca 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -96,14 +96,18 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) { case Basic_i16: ssa_fprintf(f, "i16"); break; case Basic_i32: ssa_fprintf(f, "i32"); break; case Basic_i64: ssa_fprintf(f, "i64"); break; + case Basic_i128: ssa_fprintf(f, "i128"); break; case Basic_u8: ssa_fprintf(f, "i8"); break; case Basic_u16: ssa_fprintf(f, "i16"); break; case Basic_u32: ssa_fprintf(f, "i32"); break; case Basic_u64: ssa_fprintf(f, "i64"); break; + case Basic_u128: ssa_fprintf(f, "u128"); break; + case Basic_f16: ssa_fprintf(f, "half"); break; case Basic_f32: ssa_fprintf(f, "float"); break; case Basic_f64: ssa_fprintf(f, "double"); break; - case Basic_rawptr: ssa_fprintf(f, "%%-rawptr"); break; - case Basic_string: ssa_fprintf(f, "%%-string"); break; + case Basic_f128: ssa_fprintf(f, "fp128"); break; + case Basic_rawptr: ssa_fprintf(f, "%%.rawptr"); break; + case Basic_string: ssa_fprintf(f, "%%.string"); break; case Basic_uint: ssa_fprintf(f, "i%lld", word_bits); break; case Basic_int: ssa_fprintf(f, "i%lld", word_bits); break; } @@ -113,6 +117,12 @@ void ssa_print_type(gbFile *f, BaseTypeSizes s, Type *t) { ssa_print_type(f, s, t->array.elem); ssa_fprintf(f, "]"); break; + case Type_Vector: { + // TODO(bill): actually do correctly + ssa_fprintf(f, "<%lld x ", t->vector.count); + ssa_print_type(f, s, t->vector.elem); + ssa_fprintf(f, ">"); + } break; case Type_Slice: ssa_fprintf(f, "{"); ssa_print_type(f, s, t->slice.elem); @@ -366,11 +376,15 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { case ssaInstr_BinaryOp: { auto *bo = &value->instr.binary_op; Type *type = ssa_value_type(bo->left); + Type *elem_type = type; + while (elem_type->kind == Type_Vector) { + elem_type = elem_type->vector.elem; + } ssa_fprintf(f, "%%%d = ", value->id); if (gb_is_between(bo->op.kind, Token__ComparisonBegin+1, Token__ComparisonEnd-1)) { - if (is_type_float(type)) { + if (is_type_float(elem_type)) { ssa_fprintf(f, "fcmp "); switch (bo->op.kind) { case Token_CmpEq: ssa_fprintf(f, "oeq"); break; @@ -384,7 +398,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { ssa_fprintf(f, "icmp "); if (bo->op.kind != Token_CmpEq && bo->op.kind != Token_NotEq) { - if (is_type_unsigned(type)) { + if (is_type_unsigned(elem_type)) { ssa_fprintf(f, "u"); } else { ssa_fprintf(f, "s"); @@ -400,24 +414,25 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { } } } else { - if (is_type_float(type)) + if (is_type_float(elem_type)) ssa_fprintf(f, "f"); switch (bo->op.kind) { case Token_Add: ssa_fprintf(f, "add"); break; case Token_Sub: ssa_fprintf(f, "sub"); break; case Token_And: ssa_fprintf(f, "and"); break; - case Token_Or: ssa_fprintf(f, "or"); break; + case Token_Or: ssa_fprintf(f, "or"); break; case Token_Xor: ssa_fprintf(f, "xor"); break; + case Token_Shl: ssa_fprintf(f, "shl"); break; + case Token_Shr: ssa_fprintf(f, "lshr"); break; + case Token_Mul: ssa_fprintf(f, "mul"); break; case Token_AndNot: GB_PANIC("Token_AndNot Should never be called"); - case Token_Mul: ssa_fprintf(f, "mul"); break; - default: { - if (!is_type_float(type)) { - if (is_type_unsigned(type)) ssa_fprintf(f, "u"); - else ssa_fprintf(f, "s"); + if (!is_type_float(elem_type)) { + if (is_type_unsigned(elem_type)) ssa_fprintf(f, "u"); + else ssa_fprintf(f, "s"); } switch (bo->op.kind) { @@ -483,12 +498,12 @@ void ssa_print_llvm_ir(gbFile *f, ssaModule *m) { ssa_fprintf(f, "target datalayout = %.*s\n", LIT(m->layout)); } - ssa_print_encoded_local(f, make_string("-string")); + ssa_print_encoded_local(f, make_string(".string")); ssa_fprintf(f, " = type {i8*, "); ssa_print_type(f, m->sizes, t_int); ssa_fprintf(f, "} ; Basic_string\n\n"); - ssa_print_encoded_local(f, make_string("-rawptr")); + ssa_print_encoded_local(f, make_string(".rawptr")); ssa_fprintf(f, " = type i8*"); ssa_fprintf(f, " ; Basic_rawptr\n\n"); diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 310e1c423..57887d3f1 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -284,8 +284,15 @@ Type *ssa_instr_type(ssaInstr *instr) { return instr->binary_op.type; case ssaInstr_Conv: return instr->conv.to; - case ssaInstr_Call: - return instr->call.type; + case ssaInstr_Call: { + Type *pt = instr->call.type; + GB_ASSERT(pt->kind == Type_Proc); + auto *tuple = &pt->proc.results->tuple; + if (tuple->variable_count != 1) + return pt->proc.results; + else + return tuple->variables[0]->type; + } } return NULL; } @@ -560,12 +567,28 @@ b32 ssa_is_blank_ident(AstNode *node) { } +ssaInstr *ssa_get_last_instr(ssaBlock *block) { + isize len = gb_array_count(block->instrs); + if (len > 0) { + ssaValue *v = block->instrs[len-1]; + GB_ASSERT(v->kind == ssaValue_Instr); + return &v->instr; + } + return NULL; + +} ssaValue *ssa_emit(ssaProcedure *proc, ssaValue *instr) { ssaBlock *b = proc->curr_block; instr->instr.parent = b; if (b) { - gb_array_append(b->instrs, instr); + ssaInstr *i = ssa_get_last_instr(b); + if (i && (i->kind == ssaInstr_Ret || i->kind == ssaInstr_Unreachable)) { + // NOTE(bill): any instruction in the current block after a `ret` + // or an `unreachable`, is never executed + } else { + gb_array_append(b->instrs, instr); + } } return instr; } @@ -688,11 +711,13 @@ void ssa_emit_if(ssaProcedure *proc, ssaValue *cond, ssaBlock *true_block, ssaBl ssaBlock *ssa__make_block(ssaProcedure *proc, AstNode *node, String label) { Scope *scope = NULL; - Scope **found = map_get(&proc->module->info->scopes, hash_pointer(node)); - if (found) { - scope = *found; - } else { - GB_PANIC("Block scope not found"); + if (node != NULL) { + Scope **found = map_get(&proc->module->info->scopes, hash_pointer(node)); + if (found) { + scope = *found; + } else { + GB_PANIC("Block scope not found for %.*s", LIT(ast_node_strings[node->kind])); + } } ssaValue *block = ssa_make_value_block(proc, node, scope, label); @@ -1021,6 +1046,8 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { Type *src = get_base_type(src_type); Type *dst = get_base_type(t); + if (are_types_identical(t, src_type)) + return value; if (value->kind == ssaValue_Constant) { if (dst->kind == Type_Basic) @@ -1035,6 +1062,12 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { if (dz >= sz) { kind = ssaConv_zext; } + + if (sz == dz) { + // NOTE(bill): In LLVM, all integers are signed and rely upon 2's compliment + return value; + } + return ssa_emit(proc, ssa_make_instr_conv(proc, kind, value, src, dst)); } @@ -1117,7 +1150,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case_ast_node(i, Ident, expr); Entity *e = *map_get(&proc->module->info->uses, hash_pointer(expr)); if (e->kind == Entity_Builtin) { - GB_PANIC("TODO(bill): Entity_Builtin"); + GB_PANIC("TODO(bill): ssa_build_single_expr Entity_Builtin"); return NULL; } @@ -1181,6 +1214,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case Token_Or: case Token_Xor: case Token_AndNot: + case Token_Shl: + case Token_Shr: return ssa_emit_arith(proc, be->op, ssa_build_expr(proc, be->left), ssa_build_expr(proc, be->right), |