mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 08:08:50 +00:00
Fix interval loop constant bug; Fix ir edge checking; Fix vector arithmetic with scalars
This commit is contained in:
+7
-8
@@ -319,15 +319,14 @@ look_at :: proc(eye, centre, up: Vec3) -> Mat4 {
|
|||||||
s := norm(cross(f, up));
|
s := norm(cross(f, up));
|
||||||
u := cross(s, f);
|
u := cross(s, f);
|
||||||
|
|
||||||
m: Mat4;
|
return Mat4{
|
||||||
|
{+s.x, +u.x, -f.x, 0},
|
||||||
m[0] = [4]f32{+s.x, +s.y, +s.z, 0};
|
{+s.y, +u.y, -f.y, 0},
|
||||||
m[1] = [4]f32{+u.x, +u.y, +u.z, 0};
|
{+s.z, +u.z, -f.z, 0},
|
||||||
m[2] = [4]f32{-f.x, -f.y, -f.z, 0};
|
{-dot(s, eye), -dot(u, eye), dot(f, eye), 1},
|
||||||
m[3] = [4]f32{dot(s, eye), dot(u, eye), dot(f, eye), 1};
|
};
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
perspective :: proc(fovy, aspect, near, far: f32) -> Mat4 {
|
perspective :: proc(fovy, aspect, near, far: f32) -> Mat4 {
|
||||||
m: Mat4;
|
m: Mat4;
|
||||||
tan_half_fovy := tan(0.5 * fovy);
|
tan_half_fovy := tan(0.5 * fovy);
|
||||||
|
|||||||
+29
-40
@@ -3345,10 +3345,15 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool vari_expand = (ce->ellipsis.pos.line != 0);
|
||||||
|
if (vari_expand && id != BuiltinProc_append) {
|
||||||
|
error(ce->ellipsis, "Invalid use of `..` with built-in procedure `append`");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case BuiltinProc_new:
|
case BuiltinProc_new:
|
||||||
// case BuiltinProc_new_slice:
|
|
||||||
case BuiltinProc_make:
|
case BuiltinProc_make:
|
||||||
case BuiltinProc_size_of:
|
case BuiltinProc_size_of:
|
||||||
case BuiltinProc_align_of:
|
case BuiltinProc_align_of:
|
||||||
@@ -4083,50 +4088,34 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
check_expr(c, &z, ce->args.e[2]); if (z.mode == Addressing_Invalid) return false;
|
check_expr(c, &z, ce->args.e[2]); if (z.mode == Addressing_Invalid) return false;
|
||||||
check_expr(c, &w, ce->args.e[3]); if (w.mode == Addressing_Invalid) return false;
|
check_expr(c, &w, ce->args.e[3]); if (w.mode == Addressing_Invalid) return false;
|
||||||
|
|
||||||
convert_to_typed(c, &x, y.type, 0); if (x.mode == Addressing_Invalid) return false;
|
#define _QUAT_CTT(x, y, z, w) do { \
|
||||||
convert_to_typed(c, &x, z.type, 0); if (x.mode == Addressing_Invalid) return false;
|
convert_to_typed(c, &(x), (y).type, 0); if ((x).mode == Addressing_Invalid) return false; \
|
||||||
convert_to_typed(c, &x, w.type, 0); if (x.mode == Addressing_Invalid) return false;
|
convert_to_typed(c, &(x), (z).type, 0); if ((x).mode == Addressing_Invalid) return false; \
|
||||||
|
convert_to_typed(c, &(x), (w).type, 0); if ((x).mode == Addressing_Invalid) return false; \
|
||||||
convert_to_typed(c, &y, z.type, 0); if (y.mode == Addressing_Invalid) return false;
|
} while (0)
|
||||||
convert_to_typed(c, &y, w.type, 0); if (y.mode == Addressing_Invalid) return false;
|
_QUAT_CTT(x, y, z, w);
|
||||||
convert_to_typed(c, &y, x.type, 0); if (y.mode == Addressing_Invalid) return false;
|
_QUAT_CTT(y, z, w, x);
|
||||||
|
_QUAT_CTT(z, w, x, y);
|
||||||
convert_to_typed(c, &z, y.type, 0); if (z.mode == Addressing_Invalid) return false;
|
_QUAT_CTT(w, x, y, z);
|
||||||
convert_to_typed(c, &z, w.type, 0); if (z.mode == Addressing_Invalid) return false;
|
#undef _QUAT_CTT
|
||||||
convert_to_typed(c, &z, x.type, 0); if (z.mode == Addressing_Invalid) return false;
|
|
||||||
|
|
||||||
convert_to_typed(c, &w, x.type, 0); if (w.mode == Addressing_Invalid) return false;
|
|
||||||
convert_to_typed(c, &w, y.type, 0); if (w.mode == Addressing_Invalid) return false;
|
|
||||||
convert_to_typed(c, &w, z.type, 0); if (w.mode == Addressing_Invalid) return false;
|
|
||||||
|
|
||||||
if (x.mode == Addressing_Constant &&
|
if (x.mode == Addressing_Constant &&
|
||||||
y.mode == Addressing_Constant &&
|
y.mode == Addressing_Constant &&
|
||||||
z.mode == Addressing_Constant &&
|
z.mode == Addressing_Constant &&
|
||||||
w.mode == Addressing_Constant) {
|
w.mode == Addressing_Constant) {
|
||||||
if (is_type_numeric(x.type) &&
|
#define _QUAT_EXACT_VAL(x) do { \
|
||||||
exact_value_imag(x.value).value_float == 0 &&
|
if (is_type_numeric((x).type) && \
|
||||||
exact_value_jmag(x.value).value_float == 0 &&
|
exact_value_imag((x).value).value_float == 0 && \
|
||||||
exact_value_kmag(x.value).value_float == 0) {
|
exact_value_jmag((x).value).value_float == 0 && \
|
||||||
x.type = t_untyped_float;
|
exact_value_kmag((x).value).value_float == 0) { \
|
||||||
}
|
(x).type = t_untyped_float; \
|
||||||
if (is_type_numeric(y.type) &&
|
} \
|
||||||
exact_value_imag(y.value).value_float == 0 &&
|
} while (0)
|
||||||
exact_value_jmag(y.value).value_float == 0 &&
|
_QUAT_EXACT_VAL(x);
|
||||||
exact_value_kmag(y.value).value_float == 0) {
|
_QUAT_EXACT_VAL(y);
|
||||||
y.type = t_untyped_float;
|
_QUAT_EXACT_VAL(z);
|
||||||
}
|
_QUAT_EXACT_VAL(w);
|
||||||
if (is_type_numeric(z.type) &&
|
#undef _QUAT_EXACT_VAL
|
||||||
exact_value_imag(z.value).value_float == 0 &&
|
|
||||||
exact_value_jmag(z.value).value_float == 0 &&
|
|
||||||
exact_value_kmag(z.value).value_float == 0) {
|
|
||||||
z.type = t_untyped_float;
|
|
||||||
}
|
|
||||||
if (is_type_numeric(w.type) &&
|
|
||||||
exact_value_imag(w.value).value_float == 0 &&
|
|
||||||
exact_value_jmag(w.value).value_float == 0 &&
|
|
||||||
exact_value_kmag(w.value).value_float == 0) {
|
|
||||||
w.type = t_untyped_float;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!are_types_identical(x.type, y.type)) {
|
if (!are_types_identical(x.type, y.type)) {
|
||||||
|
|||||||
@@ -918,6 +918,14 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (x.mode != Addressing_Constant) {
|
||||||
|
x.value = (ExactValue){0};
|
||||||
|
}
|
||||||
|
if (y.mode != Addressing_Constant) {
|
||||||
|
y.value = (ExactValue){0};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
add_type_and_value(&c->info, ie->left, x.mode, x.type, x.value);
|
add_type_and_value(&c->info, ie->left, x.mode, x.type, x.value);
|
||||||
add_type_and_value(&c->info, ie->right, y.mode, y.type, y.value);
|
add_type_and_value(&c->info, ie->right, y.mode, y.type, y.value);
|
||||||
val = type;
|
val = type;
|
||||||
|
|||||||
@@ -673,8 +673,11 @@ bool ir_is_instr_terminating(irInstr *i) {
|
|||||||
|
|
||||||
|
|
||||||
void ir_add_edge(irBlock *from, irBlock *to) {
|
void ir_add_edge(irBlock *from, irBlock *to) {
|
||||||
array_add(&from->succs, to);
|
GB_ASSERT(from->instrs.count > 0);
|
||||||
array_add(&to->preds, from);
|
if (!ir_is_instr_terminating(ir_get_last_instr(from))) {
|
||||||
|
array_add(&from->succs, to);
|
||||||
|
array_add(&to->preds, from);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_set_instr_parent(irValue *instr, irBlock *parent) {
|
void ir_set_instr_parent(irValue *instr, irBlock *parent) {
|
||||||
@@ -1812,14 +1815,15 @@ irValue *ir_emit_unary_arith(irProcedure *proc, TokenKind op, irValue *x, Type *
|
|||||||
return ir_emit(proc, ir_instr_unary_op(proc, op, x, type));
|
return ir_emit(proc, ir_instr_unary_op(proc, op, x, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *right, Type *type) {
|
irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *right, Type *type) {
|
||||||
Type *t_left = ir_type(left);
|
Type *t_left = ir_type(left);
|
||||||
Type *t_right = ir_type(right);
|
Type *t_right = ir_type(right);
|
||||||
|
|
||||||
if (is_type_vector(t_left)) {
|
if (is_type_vector(t_left) || is_type_vector(t_right)) {
|
||||||
ir_emit_comment(proc, str_lit("vector.arith.begin"));
|
ir_emit_comment(proc, str_lit("vector.arith.begin"));
|
||||||
// IMPORTANT TODO(bill): This is very wasteful with regards to stack memory
|
// IMPORTANT TODO(bill): This is very wasteful with regards to stack memory
|
||||||
Type *tl = base_type(t_left);
|
|
||||||
left = ir_emit_conv(proc, left, type);
|
left = ir_emit_conv(proc, left, type);
|
||||||
right = ir_emit_conv(proc, right, type);
|
right = ir_emit_conv(proc, right, type);
|
||||||
irValue *lhs = ir_address_from_load_or_generate_local(proc, left);
|
irValue *lhs = ir_address_from_load_or_generate_local(proc, left);
|
||||||
@@ -1828,7 +1832,8 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
|||||||
Type *elem_type = base_type(type)->Vector.elem;
|
Type *elem_type = base_type(type)->Vector.elem;
|
||||||
|
|
||||||
irValue *res = ir_add_local_generated(proc, type);
|
irValue *res = ir_add_local_generated(proc, type);
|
||||||
for (i32 i = 0; i < tl->Vector.count; i++) {
|
i64 count = base_type(type)->Vector.count;
|
||||||
|
for (i32 i = 0; i < count; i++) {
|
||||||
irValue *x = ir_emit_load(proc, ir_emit_array_epi(proc, lhs, i));
|
irValue *x = ir_emit_load(proc, ir_emit_array_epi(proc, lhs, i));
|
||||||
irValue *y = ir_emit_load(proc, ir_emit_array_epi(proc, rhs, i));
|
irValue *y = ir_emit_load(proc, ir_emit_array_epi(proc, rhs, i));
|
||||||
irValue *z = ir_emit_arith(proc, op, x, y, elem_type);
|
irValue *z = ir_emit_arith(proc, op, x, y, elem_type);
|
||||||
@@ -5640,7 +5645,6 @@ void ir_build_range_string(irProcedure *proc, irValue *expr, Type *val_type,
|
|||||||
done = ir_new_block(proc, NULL, "for.string.done");
|
done = ir_new_block(proc, NULL, "for.string.done");
|
||||||
|
|
||||||
irValue *offset = ir_emit_load(proc, offset_);
|
irValue *offset = ir_emit_load(proc, offset_);
|
||||||
|
|
||||||
irValue *cond = ir_emit_comp(proc, Token_Lt, offset, count);
|
irValue *cond = ir_emit_comp(proc, Token_Lt, offset, count);
|
||||||
ir_emit_if(proc, cond, body, done);
|
ir_emit_if(proc, cond, body, done);
|
||||||
ir_start_block(proc, body);
|
ir_start_block(proc, body);
|
||||||
@@ -5696,7 +5700,6 @@ void ir_build_range_interval(irProcedure *proc, AstNodeBinaryExpr *node, Type *v
|
|||||||
body = ir_new_block(proc, NULL, "for.interval.body");
|
body = ir_new_block(proc, NULL, "for.interval.body");
|
||||||
done = ir_new_block(proc, NULL, "for.interval.done");
|
done = ir_new_block(proc, NULL, "for.interval.done");
|
||||||
|
|
||||||
upper = ir_build_expr(proc, node->right);
|
|
||||||
|
|
||||||
TokenKind op = Token_Lt;
|
TokenKind op = Token_Lt;
|
||||||
switch (node->op.kind) {
|
switch (node->op.kind) {
|
||||||
@@ -5704,6 +5707,9 @@ void ir_build_range_interval(irProcedure *proc, AstNodeBinaryExpr *node, Type *v
|
|||||||
case Token_HalfClosed: op = Token_Lt; break;
|
case Token_HalfClosed: op = Token_Lt; break;
|
||||||
default: GB_PANIC("Invalid interval operator"); break;
|
default: GB_PANIC("Invalid interval operator"); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upper = ir_build_expr(proc, node->right);
|
||||||
|
|
||||||
irValue *cond = ir_emit_comp(proc, op, ir_emit_load(proc, value), upper);
|
irValue *cond = ir_emit_comp(proc, op, ir_emit_load(proc, value), upper);
|
||||||
ir_emit_if(proc, cond, body, done);
|
ir_emit_if(proc, cond, body, done);
|
||||||
ir_start_block(proc, body);
|
ir_start_block(proc, body);
|
||||||
@@ -6222,7 +6228,6 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
|||||||
GB_PANIC("TODO(bill): enum core type %s", type_to_string(core_elem));
|
GB_PANIC("TODO(bill): enum core type %s", type_to_string(core_elem));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Type *expr_type = type_of_expr(proc->module->info, rs->expr);
|
Type *expr_type = type_of_expr(proc->module->info, rs->expr);
|
||||||
Type *et = base_type(type_deref(expr_type));
|
Type *et = base_type(type_deref(expr_type));
|
||||||
|
|||||||
+1
-1
@@ -1060,7 +1060,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
irInstrBinaryOp *bo = &value->Instr.BinaryOp;
|
irInstrBinaryOp *bo = &value->Instr.BinaryOp;
|
||||||
Type *type = base_type(ir_type(bo->left));
|
Type *type = base_type(ir_type(bo->left));
|
||||||
Type *elem_type = type;
|
Type *elem_type = type;
|
||||||
GB_ASSERT(!is_type_vector(elem_type));
|
GB_ASSERT_MSG(!is_type_vector(elem_type), type_to_string(elem_type));
|
||||||
|
|
||||||
ir_fprintf(f, "%%%d = ", value->index);
|
ir_fprintf(f, "%%%d = ", value->index);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user