Add x y z w fields to quaternion types; Improve linalg quaternion mathematics

This commit is contained in:
gingerBill
2020-01-01 16:14:00 +00:00
parent e9e2ab240d
commit 16a7c55334
5 changed files with 299 additions and 62 deletions
+42
View File
@@ -3313,6 +3313,48 @@ ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selecti
if (success_) *success_ = true;
return value;
} else if (value.kind == ExactValue_Quaternion) {
// @QuaternionLayout
Quaternion256 q = value.value_quaternion;
GB_ASSERT(sel.index.count == 1);
switch (sel.index[0]) {
case 3: // w
if (success_) *success_ = true;
return exact_value_float(q.real);
case 0: // x
if (success_) *success_ = true;
return exact_value_float(q.imag);
case 1: // y
if (success_) *success_ = true;
return exact_value_float(q.jmag);
case 2: // z
if (success_) *success_ = true;
return exact_value_float(q.kmag);
}
if (success_) *success_ = false;
return empty_exact_value;
} else if (value.kind == ExactValue_Complex) {
// @QuaternionLayout
Complex128 c = value.value_complex;
GB_ASSERT(sel.index.count == 1);
switch (sel.index[0]) {
case 0: // real
if (success_) *success_ = true;
return exact_value_float(c.real);
case 1: // imag
if (success_) *success_ = true;
return exact_value_float(c.imag);
}
if (success_) *success_ = false;
return empty_exact_value;
}
if (success_) *success_ = true;
+20 -1
View File
@@ -4783,6 +4783,14 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
// NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
if (s->kind == irValue_Instr) {
if (s->Instr.kind == irInstr_Load) {
irValue *addr = s->Instr.Load.address;
irValue *ptr = ir_emit_struct_ep(proc, addr, index);
return ir_emit_load(proc, ptr);
}
}
gbAllocator a = ir_allocator();
Type *t = base_type(ir_type(s));
Type *result_type = nullptr;
@@ -4889,7 +4897,9 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel) {
}
type = core_type(type);
if (is_type_raw_union(type)) {
if (is_type_quaternion(type)) {
e = ir_emit_struct_ep(proc, e, index);
} else if (is_type_raw_union(type)) {
type = type->Struct.fields[index]->type;
GB_ASSERT(is_type_pointer(ir_type(e)));
e = ir_emit_bitcast(proc, e, alloc_type_pointer(type));
@@ -4942,6 +4952,15 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel) {
irValue *ir_emit_deep_field_ev(irProcedure *proc, irValue *e, Selection sel) {
GB_ASSERT(sel.index.count > 0);
if (e->kind == irValue_Instr) {
if (e->Instr.kind == irInstr_Load) {
irValue *addr = e->Instr.Load.address;
irValue *ptr = ir_emit_deep_field_gep(proc, addr, sel);
return ir_emit_load(proc, ptr);
}
}
Type *type = ir_type(e);
for_array(i, sel.index) {
+88
View File
@@ -2333,6 +2333,94 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
}
#endif
} break;
case Basic_quaternion128: {
// @QuaternionLayout
gb_local_persist String w = str_lit("w");
gb_local_persist String x = str_lit("x");
gb_local_persist String y = str_lit("y");
gb_local_persist String z = str_lit("z");
gb_local_persist Entity *entity__w = alloc_entity_field(nullptr, make_token_ident(w), t_f32, false, 3);
gb_local_persist Entity *entity__x = alloc_entity_field(nullptr, make_token_ident(x), t_f32, false, 0);
gb_local_persist Entity *entity__y = alloc_entity_field(nullptr, make_token_ident(y), t_f32, false, 1);
gb_local_persist Entity *entity__z = alloc_entity_field(nullptr, make_token_ident(z), t_f32, false, 2);
if (field_name == w) {
selection_add_index(&sel, 3);
sel.entity = entity__w;
return sel;
} else if (field_name == x) {
selection_add_index(&sel, 0);
sel.entity = entity__x;
return sel;
} else if (field_name == y) {
selection_add_index(&sel, 1);
sel.entity = entity__y;
return sel;
} else if (field_name == z) {
selection_add_index(&sel, 2);
sel.entity = entity__z;
return sel;
}
} break;
case Basic_quaternion256: {
// @QuaternionLayout
gb_local_persist String w = str_lit("w");
gb_local_persist String x = str_lit("x");
gb_local_persist String y = str_lit("y");
gb_local_persist String z = str_lit("z");
gb_local_persist Entity *entity__w = alloc_entity_field(nullptr, make_token_ident(w), t_f64, false, 3);
gb_local_persist Entity *entity__x = alloc_entity_field(nullptr, make_token_ident(x), t_f64, false, 0);
gb_local_persist Entity *entity__y = alloc_entity_field(nullptr, make_token_ident(y), t_f64, false, 1);
gb_local_persist Entity *entity__z = alloc_entity_field(nullptr, make_token_ident(z), t_f64, false, 2);
if (field_name == w) {
selection_add_index(&sel, 3);
sel.entity = entity__w;
return sel;
} else if (field_name == x) {
selection_add_index(&sel, 0);
sel.entity = entity__x;
return sel;
} else if (field_name == y) {
selection_add_index(&sel, 1);
sel.entity = entity__y;
return sel;
} else if (field_name == z) {
selection_add_index(&sel, 2);
sel.entity = entity__z;
return sel;
}
} break;
case Basic_UntypedQuaternion: {
// @QuaternionLayout
gb_local_persist String w = str_lit("w");
gb_local_persist String x = str_lit("x");
gb_local_persist String y = str_lit("y");
gb_local_persist String z = str_lit("z");
gb_local_persist Entity *entity__w = alloc_entity_field(nullptr, make_token_ident(w), t_untyped_float, false, 3);
gb_local_persist Entity *entity__x = alloc_entity_field(nullptr, make_token_ident(x), t_untyped_float, false, 0);
gb_local_persist Entity *entity__y = alloc_entity_field(nullptr, make_token_ident(y), t_untyped_float, false, 1);
gb_local_persist Entity *entity__z = alloc_entity_field(nullptr, make_token_ident(z), t_untyped_float, false, 2);
if (field_name == w) {
selection_add_index(&sel, 3);
sel.entity = entity__w;
return sel;
} else if (field_name == x) {
selection_add_index(&sel, 0);
sel.entity = entity__x;
return sel;
} else if (field_name == y) {
selection_add_index(&sel, 1);
sel.entity = entity__y;
return sel;
} else if (field_name == z) {
selection_add_index(&sel, 2);
sel.entity = entity__z;
return sel;
}
} break;
}
return sel;