diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-05-01 00:38:26 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-05-01 00:38:26 +0100 |
| commit | 04f5fff7fa65624cdbc80c5dad83241e31da18e7 (patch) | |
| tree | e2fc093df5cb932c070755fdb211c1433b4884f9 /src | |
| parent | dc5587eae248cb2684536dc4cd01a13e6c6a5ca4 (diff) | |
Improve vector math; Make bprint* return string
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_expr.c | 101 | ||||
| -rw-r--r-- | src/ir.c | 18 | ||||
| -rw-r--r-- | src/ir_print.c | 11 | ||||
| -rw-r--r-- | src/types.c | 12 |
4 files changed, 116 insertions, 26 deletions
diff --git a/src/check_expr.c b/src/check_expr.c index db0ea2eb8..5491e4f6c 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -233,6 +233,14 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) { } } + if (is_type_vector(dst)) { + Type *elem = base_vector_type(dst); + i64 distance = check_distance_between_types(c, operand, elem); + if (distance >= 0) { + return distance + 5; + } + } + if (is_type_any(dst)) { // NOTE(bill): Anything can cast to `Any` @@ -288,9 +296,13 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n add_type_info_type(c, target_type); } - convert_to_typed(c, operand, target_type, 0); - if (operand->mode == Addressing_Invalid) { - return; + if (target_type != NULL && is_type_vector(target_type)) { + // NOTE(bill): continue to below + } else { + convert_to_typed(c, operand, target_type, 0); + if (operand->mode == Addressing_Invalid) { + return; + } } } @@ -1096,6 +1108,33 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) { } } break; } + } else if (str_eq(build_context.ODIN_OS, str_lit("linux"))) { + Type *bt = core_type(original_type); + switch (bt->kind) { + // Okay to pass by value + // Especially the only Odin types + case Type_Basic: break; + case Type_Pointer: break; + case Type_Proc: break; // NOTE(bill): Just a pointer + + // Odin only types + case Type_Slice: + case Type_DynamicArray: + case Type_Map: + break; + + // Odin specific + case Type_Array: + case Type_Vector: + // Could be in C too + case Type_Record: { + i64 align = type_align_of(a, original_type); + i64 size = type_size_of(a, original_type); + if (8*size > 16) { + new_type = make_type_pointer(a, original_type); + } + } break; + } } else { // IMPORTANT TODO(bill): figure out the ABI settings for Linux, OSX etc. for // their architectures @@ -2453,6 +2492,8 @@ void check_cast(Checker *c, Operand *x, Type *type) { x->mode = Addressing_Value; } else if (is_type_slice(type) && is_type_string(x->type)) { x->mode = Addressing_Value; + } else if (!is_type_vector(x->type) && is_type_vector(type)) { + x->mode = Addressing_Value; } can_convert = true; } @@ -2481,6 +2522,16 @@ void check_cast(Checker *c, Operand *x, Type *type) { x->type = type; } +bool check_binary_vector_expr(Checker *c, Token op, Operand *x, Operand *y) { + if (is_type_vector(x->type) && !is_type_vector(y->type)) { + if (check_is_assignable_to(c, y, x->type)) { + if (check_binary_op(c, x, op)) { + return true; + } + } + } + return false; +} void check_binary_expr(Checker *c, Operand *x, AstNode *node) { @@ -2560,6 +2611,17 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) { return; } + + if (check_binary_vector_expr(c, op, x, y)) { + x->mode = Addressing_Value; + x->type = x->type; + return; + } + if (check_binary_vector_expr(c, op, y, x)) { + x->mode = Addressing_Value; + x->type = y->type; + return; + } if (!are_types_identical(x->type, y->type)) { if (x->type != t_invalid && y->type != t_invalid) { @@ -2737,6 +2799,24 @@ void convert_untyped_error(Checker *c, Operand *operand, Type *target_type) { operand->mode = Addressing_Invalid; } +ExactValue convert_exact_value_for_type(ExactValue v, Type *type) { + Type *t = core_type(type); + if (is_type_boolean(t)) { + // v = exact_value_to_boolean(v); + } else if (is_type_float(t)) { + v = exact_value_to_float(v); + } else if (is_type_integer(t)) { + v = exact_value_to_integer(v); + } else if (is_type_pointer(t)) { + v = exact_value_to_integer(v); + } else if (is_type_complex(t)) { + v = exact_value_to_complex(v); + } else if (is_type_quaternion(t)) { + v = exact_value_to_quaternion(v); + } + return v; +} + // NOTE(bill): Set initial level to 0 void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level) { GB_ASSERT_NOT_NULL(target_type); @@ -2747,7 +2827,6 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level return; } - if (is_type_untyped(target_type)) { GB_ASSERT(operand->type->kind == Type_Basic); GB_ASSERT(target_type->kind == Type_Basic); @@ -2809,6 +2888,18 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level } break; + case Type_Vector: { + Type *elem = base_vector_type(t); + if (check_is_assignable_to(c, operand, elem)) { + operand->mode = Addressing_Value; + } else { + operand->mode = Addressing_Invalid; + convert_untyped_error(c, operand, target_type); + return; + } + } break; + + default: if (!is_type_untyped_nil(operand->type) || !type_has_nil(target_type)) { operand->mode = Addressing_Invalid; @@ -5361,7 +5452,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t isize index = 0; isize elem_count = cl->elems.count; - if (base_type(elem_type) == t_any) { + if (is_type_any(base_type(elem_type))) { is_constant = false; } @@ -1450,13 +1450,12 @@ irValue *ir_emit_comment(irProcedure *p, String text) { return ir_emit(p, ir_instr_comment(p, text)); } -irValue *ir_copy_value_to_ptr(irProcedure *proc, irValue *val, i64 alignment) { - Type *t = ir_type(val); - i64 type_alignment = type_align_of(proc->module->allocator, t); +irValue *ir_copy_value_to_ptr(irProcedure *proc, irValue *val, Type *new_type, i64 alignment) { + i64 type_alignment = type_align_of(proc->module->allocator, new_type); if (alignment < type_alignment) { alignment = type_alignment; } - irValue *ptr = ir_add_local_generated(proc, t); + irValue *ptr = ir_add_local_generated(proc, new_type); ptr->Instr.Local.alignment = alignment; ir_emit_store(proc, ptr, val); return ptr; @@ -1480,7 +1479,7 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, irValue **args, isize arg_ Type *new_type = pt->Proc.abi_compat_params[i]; if (original_type != new_type) { if (is_type_pointer(new_type)) { - args[i] = ir_copy_value_to_ptr(p, args[i], 16); + args[i] = ir_copy_value_to_ptr(p, args[i], original_type, 16); } else if (is_type_integer(new_type)) { args[i] = ir_emit_transmute(p, args[i], new_type); } @@ -3546,6 +3545,15 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { GB_ASSERT_NOT_NULL(tv); if (tv->value.kind != ExactValue_Invalid) { + // NOTE(bill): Edge case + if (tv->value.kind != ExactValue_Compound && + is_type_vector(tv->type)) { + Type *elem = base_vector_type(tv->type); + ExactValue value = convert_exact_value_for_type(tv->value, elem); + irValue *x = ir_add_module_constant(proc->module, elem, value); + return ir_emit_conv(proc, x, tv->type); + } + return ir_add_module_constant(proc->module, tv->type, tv->value); } diff --git a/src/ir_print.c b/src/ir_print.c index 08de766af..8a069c856 100644 --- a/src/ir_print.c +++ b/src/ir_print.c @@ -354,13 +354,7 @@ void ir_print_compound_element(irFileBuffer *f, irModule *m, ExactValue v, Type void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *type) { type = core_type(type); - if (is_type_float(type)) { - value = exact_value_to_float(value); - } else if (is_type_integer(type)) { - value = exact_value_to_integer(value); - } else if (is_type_pointer(type)) { - value = exact_value_to_integer(value); - } + value = convert_exact_value_for_type(value, type); switch (value.kind) { case ExactValue_Bool: @@ -1076,9 +1070,6 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { Type *type = base_type(ir_type(bo->left)); Type *elem_type = type; GB_ASSERT(!is_type_vector(elem_type)); - while (elem_type->kind == Type_Vector) { - elem_type = base_type(elem_type->Vector.elem); - } ir_fprintf(f, "%%%d = ", value->index); diff --git a/src/types.c b/src/types.c index f98db66e9..be8362163 100644 --- a/src/types.c +++ b/src/types.c @@ -1437,16 +1437,16 @@ void type_path_free(TypePath *tp) { TypePath *type_path_push(TypePath *tp, Type *t) { GB_ASSERT(tp != NULL); - for (isize i = 0; i < tp->path.count; i++) { + for (isize i = 1; i < tp->path.count; i++) { if (tp->path.e[i] == t) { // TODO(bill): - GB_ASSERT(is_type_named(t)); + GB_ASSERT_MSG(is_type_named(t), "%s", type_to_string(t)); Entity *e = t->Named.type_name; error(e->token, "Illegal declaration cycle of `%.*s`", LIT(t->Named.name)); // NOTE(bill): Print cycle, if it's deep enough - for (isize j = 0; j < tp->path.count; j++) { + for (isize j = i; j < tp->path.count; j++) { Type *t = tp->path.e[j]; - GB_ASSERT(is_type_named(t)); + GB_ASSERT_MSG(is_type_named(t), "%s", type_to_string(t)); Entity *e = t->Named.type_name; error(e->token, "\t%.*s refers to", LIT(t->Named.name)); } @@ -1461,14 +1461,14 @@ TypePath *type_path_push(TypePath *tp, Type *t) { } } - if (!tp->failure) { + if (!tp->failure && is_type_named(t)) { array_add(&tp->path, t); } return tp; } void type_path_pop(TypePath *tp) { - if (tp != NULL) { + if (tp != NULL && tp->path.count > 0) { array_pop(&tp->path); } } |