mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-22 09:53:23 +00:00
Merge branch 'master' into windows-llvm-13.0.0
This commit is contained in:
@@ -1927,27 +1927,28 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
fi.indent += 1
|
||||
|
||||
if fi.hash {
|
||||
// Printed as it is written
|
||||
io.write_byte(fi.writer, '\n')
|
||||
// TODO(bill): Should this render it like in written form? e.g. tranposed
|
||||
for row in 0..<info.row_count {
|
||||
for col in 0..<info.column_count {
|
||||
fmt_write_indent(fi)
|
||||
for col in 0..<info.column_count {
|
||||
if col > 0 { io.write_string(fi.writer, ", ") }
|
||||
for row in 0..<info.row_count {
|
||||
if row > 0 { io.write_string(fi.writer, ", ") }
|
||||
|
||||
offset := (row + col*info.elem_stride)*info.elem_size
|
||||
offset := (col + row*info.elem_stride)*info.elem_size
|
||||
|
||||
data := uintptr(v.data) + uintptr(offset)
|
||||
fmt_arg(fi, any{rawptr(data), info.elem.id}, verb)
|
||||
}
|
||||
io.write_string(fi.writer, ";\n")
|
||||
io.write_string(fi.writer, ",\n")
|
||||
}
|
||||
} else {
|
||||
for row in 0..<info.row_count {
|
||||
if row > 0 { io.write_string(fi.writer, ", ") }
|
||||
for col in 0..<info.column_count {
|
||||
if col > 0 { io.write_string(fi.writer, "; ") }
|
||||
// Printed in Row-Major layout to match text layout
|
||||
for col in 0..<info.column_count {
|
||||
if col > 0 { io.write_string(fi.writer, "; ") }
|
||||
for row in 0..<info.row_count {
|
||||
if row > 0 { io.write_string(fi.writer, ", ") }
|
||||
|
||||
offset := (row + col*info.elem_stride)*info.elem_size
|
||||
offset := (col + row*info.elem_stride)*info.elem_size
|
||||
|
||||
data := uintptr(v.data) + uintptr(offset)
|
||||
fmt_arg(fi, any{rawptr(data), info.elem.id}, verb)
|
||||
|
||||
@@ -38,12 +38,12 @@ inverse :: proc{
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
hermitian_adjoint :: proc(m: $M/matrix[$N, N]$T) -> M where intrinsics.type_is_complex(T), N >= 1 {
|
||||
hermitian_adjoint :: proc "contextless" (m: $M/matrix[$N, N]$T) -> M where intrinsics.type_is_complex(T), N >= 1 {
|
||||
return conj(transpose(m))
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix_trace :: proc(m: $M/matrix[$N, N]$T) -> (trace: T) {
|
||||
matrix_trace :: proc "contextless" (m: $M/matrix[$N, N]$T) -> (trace: T) {
|
||||
for i in 0..<N {
|
||||
trace += m[i, i]
|
||||
}
|
||||
@@ -51,7 +51,7 @@ matrix_trace :: proc(m: $M/matrix[$N, N]$T) -> (trace: T) {
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix_minor :: proc(m: $M/matrix[$N, N]$T, row, column: int) -> (minor: T) where N > 1 {
|
||||
matrix_minor :: proc "contextless" (m: $M/matrix[$N, N]$T, row, column: int) -> (minor: T) where N > 1 {
|
||||
K :: N-1
|
||||
cut_down: matrix[K, K]T
|
||||
for col_idx in 0..<K {
|
||||
@@ -67,23 +67,23 @@ matrix_minor :: proc(m: $M/matrix[$N, N]$T, row, column: int) -> (minor: T) wher
|
||||
|
||||
|
||||
@(builtin)
|
||||
matrix1x1_determinant :: proc(m: $M/matrix[1, 1]$T) -> (det: T) {
|
||||
matrix1x1_determinant :: proc "contextless" (m: $M/matrix[1, 1]$T) -> (det: T) {
|
||||
return m[0, 0]
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix2x2_determinant :: proc(m: $M/matrix[2, 2]$T) -> (det: T) {
|
||||
matrix2x2_determinant :: proc "contextless" (m: $M/matrix[2, 2]$T) -> (det: T) {
|
||||
return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
|
||||
}
|
||||
@(builtin)
|
||||
matrix3x3_determinant :: proc(m: $M/matrix[3, 3]$T) -> (det: T) {
|
||||
matrix3x3_determinant :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (det: T) {
|
||||
a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1])
|
||||
b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0])
|
||||
c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0])
|
||||
return a + b + c
|
||||
}
|
||||
@(builtin)
|
||||
matrix4x4_determinant :: proc(m: $M/matrix[4, 4]$T) -> (det: T) {
|
||||
matrix4x4_determinant :: proc "contextless" (m: $M/matrix[4, 4]$T) -> (det: T) {
|
||||
a := adjugate(m)
|
||||
#no_bounds_check for i in 0..<4 {
|
||||
det += m[0, i] * a[0, i]
|
||||
@@ -95,13 +95,13 @@ matrix4x4_determinant :: proc(m: $M/matrix[4, 4]$T) -> (det: T) {
|
||||
|
||||
|
||||
@(builtin)
|
||||
matrix1x1_adjugate :: proc(x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||
matrix1x1_adjugate :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||
y = x
|
||||
return
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix2x2_adjugate :: proc(x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||
matrix2x2_adjugate :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||
y[0, 0] = +x[1, 1]
|
||||
y[0, 1] = -x[1, 0]
|
||||
y[1, 0] = -x[0, 1]
|
||||
@@ -110,7 +110,7 @@ matrix2x2_adjugate :: proc(x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix3x3_adjugate :: proc(m: $M/matrix[3, 3]$T) -> (y: M) {
|
||||
matrix3x3_adjugate :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (y: M) {
|
||||
y[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2])
|
||||
y[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2])
|
||||
y[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1])
|
||||
@@ -125,7 +125,7 @@ matrix3x3_adjugate :: proc(m: $M/matrix[3, 3]$T) -> (y: M) {
|
||||
|
||||
|
||||
@(builtin)
|
||||
matrix4x4_adjugate :: proc(x: $M/matrix[4, 4]$T) -> (y: M) {
|
||||
matrix4x4_adjugate :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) {
|
||||
for i in 0..<4 {
|
||||
for j in 0..<4 {
|
||||
sign: T = 1 if (i + j) % 2 == 0 else -1
|
||||
@@ -136,13 +136,13 @@ matrix4x4_adjugate :: proc(x: $M/matrix[4, 4]$T) -> (y: M) {
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix1x1_inverse_transpose :: proc(x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||
matrix1x1_inverse_transpose :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||
y[0, 0] = 1/x[0, 0]
|
||||
return
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix2x2_inverse_transpose :: proc(x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||
matrix2x2_inverse_transpose :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
|
||||
when intrinsics.type_is_integer(T) {
|
||||
y[0, 0] = +x[1, 1] / d
|
||||
@@ -160,7 +160,7 @@ matrix2x2_inverse_transpose :: proc(x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix3x3_inverse_transpose :: proc(x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
|
||||
matrix3x3_inverse_transpose :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
|
||||
a := adjugate(x)
|
||||
d := determinant(x)
|
||||
when intrinsics.type_is_integer(T) {
|
||||
@@ -181,7 +181,7 @@ matrix3x3_inverse_transpose :: proc(x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_c
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix4x4_inverse_transpose :: proc(x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
|
||||
matrix4x4_inverse_transpose :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
|
||||
a := adjugate(x)
|
||||
d: T
|
||||
for i in 0..<4 {
|
||||
@@ -205,13 +205,13 @@ matrix4x4_inverse_transpose :: proc(x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_c
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix1x1_inverse :: proc(x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||
matrix1x1_inverse :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||
y[0, 0] = 1/x[0, 0]
|
||||
return
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix2x2_inverse :: proc(x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||
matrix2x2_inverse :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
|
||||
when intrinsics.type_is_integer(T) {
|
||||
y[0, 0] = x[1, 1] / d
|
||||
@@ -229,7 +229,7 @@ matrix2x2_inverse :: proc(x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix3x3_inverse :: proc(x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
|
||||
matrix3x3_inverse :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
|
||||
a := adjugate(x)
|
||||
d := determinant(x)
|
||||
when intrinsics.type_is_integer(T) {
|
||||
@@ -250,7 +250,7 @@ matrix3x3_inverse :: proc(x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
|
||||
}
|
||||
|
||||
@(builtin)
|
||||
matrix4x4_inverse :: proc(x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
|
||||
matrix4x4_inverse :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
|
||||
a := adjugate(x)
|
||||
d: T
|
||||
for i in 0..<4 {
|
||||
|
||||
@@ -1345,8 +1345,9 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty
|
||||
for_array(j, vd->names) {
|
||||
Ast *name = vd->names[j];
|
||||
if (!is_blank_ident(name)) {
|
||||
GB_ASSERT(name->kind == Ast_Ident);
|
||||
GB_ASSERT(name->Ident.entity != nullptr);
|
||||
if (name->kind == Ast_Ident) {
|
||||
GB_ASSERT(name->Ident.entity != nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2453,6 +2453,9 @@ bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_type_float(src) && is_type_quaternion(dst)) {
|
||||
return true;
|
||||
}
|
||||
if (is_type_complex(src) && is_type_quaternion(dst)) {
|
||||
return true;
|
||||
}
|
||||
@@ -3660,8 +3663,11 @@ bool check_index_value(CheckerContext *c, Type *main_type, bool open_range, Ast
|
||||
String lo_str = {};
|
||||
String hi_str = {};
|
||||
if (bt->Enum.fields.count > 0) {
|
||||
lo_str = bt->Enum.fields[bt->Enum.min_value_index]->token.string;
|
||||
hi_str = bt->Enum.fields[bt->Enum.max_value_index]->token.string;
|
||||
isize lo_idx = gb_clamp(bt->Enum.min_value_index, 0, bt->Enum.fields.count - 1);
|
||||
isize hi_idx = gb_clamp(bt->Enum.max_value_index, 0, bt->Enum.fields.count - 1);
|
||||
|
||||
lo_str = bt->Enum.fields[lo_idx]->token.string;
|
||||
hi_str = bt->Enum.fields[hi_idx]->token.string;
|
||||
}
|
||||
|
||||
bool out_of_bounds = false;
|
||||
|
||||
@@ -2692,7 +2692,7 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
|
||||
if (!is_partial && t->EnumeratedArray.count > bt->Enum.fields.count) {
|
||||
error(e, "Non-contiguous enumeration used as an index in an enumerated array");
|
||||
long long ea_count = cast(long long)t->EnumeratedArray.count;
|
||||
long long enum_count = cast(long long)t->Enum.fields.count;
|
||||
long long enum_count = cast(long long)bt->Enum.fields.count;
|
||||
error_line("\tenumerated array length: %lld\n", ea_count);
|
||||
error_line("\tenum field count: %lld\n", enum_count);
|
||||
error_line("\tSuggestion: prepend #partial to the enumerated array to allow for non-named elements\n");
|
||||
|
||||
@@ -1013,7 +1013,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
TypeAndValue tav = fv->value->tav;
|
||||
LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value;
|
||||
for (i64 k = lo; k < hi; k++) {
|
||||
i64 offset = matrix_index_to_offset(type, k);
|
||||
i64 offset = matrix_row_major_index_to_offset(type, k);
|
||||
GB_ASSERT(values[offset] == nullptr);
|
||||
values[offset] = val;
|
||||
}
|
||||
@@ -1023,7 +1023,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
i64 index = exact_value_to_i64(index_tav.value);
|
||||
TypeAndValue tav = fv->value->tav;
|
||||
LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value;
|
||||
i64 offset = matrix_index_to_offset(type, index);
|
||||
i64 offset = matrix_row_major_index_to_offset(type, index);
|
||||
GB_ASSERT(values[offset] == nullptr);
|
||||
values[offset] = val;
|
||||
}
|
||||
@@ -1045,7 +1045,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
for_array(i, cl->elems) {
|
||||
TypeAndValue tav = cl->elems[i]->tav;
|
||||
GB_ASSERT(tav.mode != Addressing_Invalid);
|
||||
i64 offset = matrix_index_to_offset(type, i);
|
||||
i64 offset = matrix_row_major_index_to_offset(type, i);
|
||||
values[offset] = lb_const_value(m, elem_type, tav.value, allow_local).value;
|
||||
}
|
||||
for (isize i = 0; i < total_count; i++) {
|
||||
|
||||
@@ -671,7 +671,7 @@ lbValue lb_emit_matrix_flatten(lbProcedure *p, lbValue m, Type *type) {
|
||||
for (i64 j = 0; j < column_count; j++) {
|
||||
for (i64 i = 0; i < row_count; i++) {
|
||||
lbValue src = lb_emit_matrix_ev(p, m, i, j);
|
||||
lbValue dst = lb_emit_matrix_epi(p, res.addr, i, j);
|
||||
lbValue dst = lb_emit_array_epi(p, res.addr, i + j*row_count);
|
||||
lb_emit_store(p, dst, src);
|
||||
}
|
||||
}
|
||||
@@ -1658,6 +1658,23 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
if (is_type_float(src) && is_type_complex(dst)) {
|
||||
Type *ft = base_complex_elem_type(dst);
|
||||
lbAddr gen = lb_add_local_generated(p, dst, false);
|
||||
lbValue gp = lb_addr_get_ptr(p, gen);
|
||||
lbValue real = lb_emit_conv(p, value, ft);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
|
||||
return lb_addr_load(p, gen);
|
||||
}
|
||||
if (is_type_float(src) && is_type_quaternion(dst)) {
|
||||
Type *ft = base_complex_elem_type(dst);
|
||||
lbAddr gen = lb_add_local_generated(p, dst, false);
|
||||
lbValue gp = lb_addr_get_ptr(p, gen);
|
||||
lbValue real = lb_emit_conv(p, value, ft);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
|
||||
return lb_addr_load(p, gen);
|
||||
}
|
||||
|
||||
if (is_type_complex(src) && is_type_complex(dst)) {
|
||||
Type *ft = base_complex_elem_type(dst);
|
||||
@@ -4465,7 +4482,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
|
||||
lbCompoundLitElemTempData data = {};
|
||||
data.value = value;
|
||||
|
||||
data.elem_index = cast(i32)matrix_index_to_offset(bt, k);
|
||||
data.elem_index = cast(i32)matrix_row_major_index_to_offset(bt, k);
|
||||
array_add(&temp_data, data);
|
||||
}
|
||||
|
||||
@@ -4479,7 +4496,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
|
||||
data.value = lb_emit_conv(p, value, et);
|
||||
data.expr = fv->value;
|
||||
|
||||
data.elem_index = cast(i32)matrix_index_to_offset(bt, index);
|
||||
data.elem_index = cast(i32)matrix_row_major_index_to_offset(bt, index);
|
||||
array_add(&temp_data, data);
|
||||
}
|
||||
|
||||
@@ -4489,7 +4506,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
|
||||
}
|
||||
lbCompoundLitElemTempData data = {};
|
||||
data.expr = elem;
|
||||
data.elem_index = cast(i32)matrix_index_to_offset(bt, i);
|
||||
data.elem_index = cast(i32)matrix_row_major_index_to_offset(bt, i);
|
||||
array_add(&temp_data, data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1408,12 +1408,13 @@ i64 matrix_indices_to_offset(Type *t, i64 row_index, i64 column_index) {
|
||||
i64 stride_elems = matrix_type_stride_in_elems(t);
|
||||
return stride_elems*column_index + row_index;
|
||||
}
|
||||
i64 matrix_index_to_offset(Type *t, i64 index) {
|
||||
|
||||
i64 matrix_row_major_index_to_offset(Type *t, i64 index) {
|
||||
t = base_type(t);
|
||||
GB_ASSERT(t->kind == Type_Matrix);
|
||||
|
||||
i64 row_index = index%t->Matrix.row_count;
|
||||
i64 column_index = index/t->Matrix.row_count;
|
||||
i64 column_index = index%t->Matrix.column_count;
|
||||
i64 row_index = index/t->Matrix.column_count;
|
||||
return matrix_indices_to_offset(t, row_index, column_index);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user