mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-07 18:01:30 +00:00
[qfcc] Improve support for matrix types
Their size is now calculated correctly, they can be assigned, initialized using block initializers (vectors too!), and columns can be indexed as vector lvalues.
This commit is contained in:
parent
e9d5bac369
commit
24a48ad703
5 changed files with 32 additions and 9 deletions
|
@ -1309,7 +1309,7 @@ generate_assignments (dag_t *dag, sblock_t *block, operand_t *src,
|
|||
operand_t *operands[3] = {0, 0, 0};
|
||||
daglabel_t *var;
|
||||
|
||||
if (is_structural (type) || type->width > 4) {
|
||||
if (is_structural (type) || is_matrix (type) || type->width > 4) {
|
||||
operands[0] = fix_op_type (src, type);
|
||||
operands[1] = short_operand (type_size (type), src->expr);
|
||||
for ( ; var_iter; var_iter = set_next (var_iter)) {
|
||||
|
|
|
@ -2830,11 +2830,16 @@ array_expr (const expr_t *array, const expr_t *index)
|
|||
|| ind - array_type->array.base >= array_type->array.size)) {
|
||||
return error (index, "array index out of bounds");
|
||||
}
|
||||
if (is_nonscalar (array_type)
|
||||
if (is_nonscalar (array_type) && !is_matrix (array_type)
|
||||
&& is_constant (index)
|
||||
&& (ind < 0 || ind >= array_type->width)) {
|
||||
return error (index, "array index out of bounds");
|
||||
}
|
||||
if (is_matrix (array_type)
|
||||
&& is_constant (index)
|
||||
&& (ind < 0 || ind >= array_type->columns)) {
|
||||
return error (index, "array index out of bounds");
|
||||
}
|
||||
if (is_array (array_type)) {
|
||||
ele_type = dereference_type (array_type);
|
||||
base = new_int_expr (array_type->array.base, false);
|
||||
|
@ -2842,7 +2847,10 @@ array_expr (const expr_t *array, const expr_t *index)
|
|||
ele_type = array_type->fldptr.type;
|
||||
base = new_int_expr (0, false);
|
||||
} else {
|
||||
ele_type = ev_types[array_type->type];
|
||||
ele_type = base_type (array_type);
|
||||
if (is_matrix (array_type)) {
|
||||
ele_type = vector_type (ele_type, array_type->width);
|
||||
}
|
||||
if (array->type == ex_uexpr && array->expr.op == '.') {
|
||||
auto vec = offset_pointer_expr (array->expr.e1, index);
|
||||
vec = cast_expr (pointer_type (ele_type), vec);
|
||||
|
|
|
@ -229,6 +229,10 @@ build_element_chain (element_chain_t *element_chain, const type_t *type,
|
|||
state.type = state.field->type;
|
||||
state.offset = state.field->offset;
|
||||
}
|
||||
} else if (is_matrix (type)) {
|
||||
state.type = vector_type (base_type (type), type->width);
|
||||
} else if (is_nonscalar (type)) {
|
||||
state.type = base_type (type);
|
||||
} else if (is_array (type)) {
|
||||
state.type = dereference_type (type);
|
||||
} else {
|
||||
|
|
|
@ -967,7 +967,8 @@ expr_assign (sblock_t *sblock, const expr_t *e, operand_t **op)
|
|||
|
||||
if (src_expr->type == ex_assign) {
|
||||
sblock = statement_subexpr (sblock, src_expr, &src);
|
||||
if (is_structural (dst_type) || dst_type->width > 4) {
|
||||
if (is_structural (dst_type) || is_matrix (dst_type)
|
||||
|| dst_type->width > 4) {
|
||||
return expr_assign_copy (sblock, e, op, src);
|
||||
}
|
||||
if (is_indirect (dst_expr)) {
|
||||
|
@ -976,7 +977,8 @@ expr_assign (sblock_t *sblock, const expr_t *e, operand_t **op)
|
|||
sblock = statement_subexpr (sblock, dst_expr, &dst);
|
||||
}
|
||||
} else {
|
||||
if (is_structural (dst_type) || dst_type->width > 4) {
|
||||
if (is_structural (dst_type) || is_matrix (dst_type)
|
||||
|| dst_type->width > 4) {
|
||||
return expr_assign_copy (sblock, e, op, src);
|
||||
}
|
||||
|
||||
|
|
|
@ -987,9 +987,18 @@ print_type_str (dstring_t *str, const type_t *type)
|
|||
case ev_short:
|
||||
case ev_ushort:
|
||||
case ev_double:
|
||||
dasprintf (str, " %s%s", pr_type_name[type->type],
|
||||
type->width > 1 ? va (0, "{%d}", type->width)
|
||||
: "");
|
||||
{
|
||||
const char *name = pr_type_name[type->type];
|
||||
int width = type->width;
|
||||
int cols = type->columns;
|
||||
if (cols > 1) {
|
||||
dasprintf (str, " %s{%d,%d}", name, cols, width);
|
||||
} else if (type->width > 1) {
|
||||
dasprintf (str, " %s{%d}", name, width);
|
||||
} else {
|
||||
dasprintf (str, " %s", name);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case ev_invalid:
|
||||
case ev_type_count:
|
||||
|
@ -1504,7 +1513,7 @@ type_size (const type_t *type)
|
|||
internal_error (0, "%s:%d:%d", pr_type_name[type->type],
|
||||
type->columns, type->width);
|
||||
}
|
||||
return pr_type_size[type->type] * type->width;
|
||||
return pr_type_size[type->type] * type->width * type->columns;
|
||||
case ty_struct:
|
||||
case ty_union:
|
||||
if (!type->symtab)
|
||||
|
|
Loading…
Reference in a new issue