[qfcc] Used aligned type sizes for sizeof

And geometric algebra vectors. This does break things a little in GA,
but it does bring qfcc's C closer to standard C in that sizeof respects
the alignment of the type (very important for arrays).
This commit is contained in:
Bill Currie 2023-08-29 13:59:12 +09:00
parent ad6b4057f9
commit 09cdf87f67
5 changed files with 33 additions and 5 deletions

View file

@ -230,6 +230,7 @@ int type_promotes (const type_t *dst, const type_t *src) __attribute__((pure));
int type_same (const type_t *dst, const type_t *src) __attribute__((pure));
int type_size (const type_t *type) __attribute__((pure));
int type_width (const type_t *type) __attribute__((pure));
int type_aligned_size (const type_t *type) __attribute__((pure));
void init_types (void);
void chain_initial_types (void);

View file

@ -445,6 +445,11 @@ algebra_subtype (type_t *type, attribute_t *attr)
static int
algebra_alignment (const type_t *type, int width)
{
if (width > 4) {
// don't need more than 4 units
width = 4;
}
// alignment reflects the size for doubles vs floats
return type->alignment * BITOP_RUP (width);
}
@ -657,7 +662,20 @@ algebra_type_size (const type_t *type)
return a->num_components * type_size (a->type);
} else if (type->type == ev_float || type->type == ev_double) {
auto m = type->t.multivec;
return m->num_components * type_size (m->algebra->type);
auto a = m->algebra;
auto layout = &a->layout;
int size = 0;
if (m->group_mask & (m->group_mask - 1)) {
for (int i = 0; i < layout->count; i++) {
if (m->group_mask & (1u << i)) {
auto t = algebra_mvec_type (a, m->group_mask & (1u << i));
size += type_aligned_size (t);
}
}
} else {
size = m->num_components * type_size (m->algebra->type);
}
return size;
} else {
internal_error (0, "invalid algebra type");
}

View file

@ -3009,7 +3009,7 @@ sizeof_expr (expr_t *expr, struct type_s *type)
if (!type)
type = get_type (expr);
if (type) {
expr = new_int_expr (type_size (type));
expr = new_int_expr (type_aligned_size (type));
}
return expr;
}

View file

@ -1444,6 +1444,13 @@ type_width (const type_t *type)
internal_error (0, "invalid type meta: %d", type->meta);
}
int
type_aligned_size (const type_t *type)
{
int size = type_size (type);
return RUP (size, type->alignment);
}
static void
chain_basic_types (void)
{

View file

@ -27,11 +27,13 @@ main (void)
printf ("scalar has wrong size: %d\n", sizeof (scalar_t));
return 1;
}
if (sizeof (vector_t) != 3 * sizeof (scalar_t)) {
printf ("bivector has wrong size: %d\n", sizeof (vector_t));
// vector_t is a vec3 but has alignment of 4 thus sizeof of 4 * scalar
if (sizeof (vector_t) != 4 * sizeof (scalar_t)) {
printf ("vector has wrong size: %d\n", sizeof (vector_t));
return 1;
}
if (sizeof (bivector_t) != 3 * sizeof (scalar_t)) {
// bivector_t is a vec3 but has alignment of 4 thus sizeof of 4 * scalar
if (sizeof (bivector_t) != 4 * sizeof (scalar_t)) {
printf ("bivector has wrong size: %d\n", sizeof (bivector_t));
return 1;
}