From 24a48ad7039f16f171c5bce4b859de1168cd7205 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 5 Sep 2024 14:06:30 +0900 Subject: [PATCH] [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. --- tools/qfcc/source/dags.c | 2 +- tools/qfcc/source/expr.c | 12 ++++++++++-- tools/qfcc/source/expr_compound.c | 4 ++++ tools/qfcc/source/statements.c | 6 ++++-- tools/qfcc/source/type.c | 17 +++++++++++++---- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/tools/qfcc/source/dags.c b/tools/qfcc/source/dags.c index 47d332191..d6820b3fe 100644 --- a/tools/qfcc/source/dags.c +++ b/tools/qfcc/source/dags.c @@ -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)) { diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 081613982..82842b8b7 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -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); diff --git a/tools/qfcc/source/expr_compound.c b/tools/qfcc/source/expr_compound.c index b74150d03..1a540f70a 100644 --- a/tools/qfcc/source/expr_compound.c +++ b/tools/qfcc/source/expr_compound.c @@ -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 { diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c index b031a8200..8771bd4be 100644 --- a/tools/qfcc/source/statements.c +++ b/tools/qfcc/source/statements.c @@ -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); } diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index 6aa0c87c9..bbb9c3c99 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -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)