aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-05-01 00:38:26 +0100
committerGinger Bill <bill@gingerbill.org>2017-05-01 00:38:26 +0100
commit04f5fff7fa65624cdbc80c5dad83241e31da18e7 (patch)
treee2fc093df5cb932c070755fdb211c1433b4884f9 /src
parentdc5587eae248cb2684536dc4cd01a13e6c6a5ca4 (diff)
Improve vector math; Make bprint* return string
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.c101
-rw-r--r--src/ir.c18
-rw-r--r--src/ir_print.c11
-rw-r--r--src/types.c12
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;
}
diff --git a/src/ir.c b/src/ir.c
index 1119b4b12..f8fa30403 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -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);
}
}