arm64: use union type tags in HFA classification

This commit is contained in:
Benjamin Oldenburg 2026-03-16 01:09:10 +07:00
parent 684acad263
commit 6cb9d7ae53
3 changed files with 20 additions and 19 deletions

View File

@ -778,28 +778,10 @@ static int arm64_hfa_aux(CType *type, int *fsize, int num)
return num + 1;
}
else if ((type->t & VT_BTYPE) == VT_STRUCT) {
int is_struct = 1; /* assume struct, check if union */
Sym *field;
if (!type->ref)
return -1;
/* A union has all fields at offset 0, a struct has increasing offsets */
for (field = type->ref->next; field; field = field->next)
if (field->c != 0) {
is_struct = 1;
break;
}
/* If all fields are at offset 0 and there's more than one field, it's a union */
if (type->ref->next && type->ref->next->next && !type->ref->next->c) {
/* Check if all fields are at offset 0 (union) */
int all_zero = 1;
for (field = type->ref->next; field; field = field->next)
if (field->c != 0) {
all_zero = 0;
break;
}
is_struct = !all_zero;
}
if (is_struct) {
if (!IS_UNION(type->t)) {
int num0 = num;
for (field = type->ref->next; field; field = field->next) {
if (field->c != (num - num0) * *fsize)

View File

@ -38,6 +38,11 @@ struct hfa32 { long double a, b; } hfa32 = { 32.1, 32.2 };
struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 };
struct hfa34 { long double a, b, c, d; } hfa34 = { 34.1, 34.2, 34.3, 34.4 };
struct empty { };
/* Keep the top-level offsets at zero without changing the type into a union. */
struct hfae12 { struct empty e; struct hfa12 h; } hfae12 = { { }, { 112.1, 112.2 } };
struct hfae22 { struct empty e; struct hfa22 h; } hfae22 = { { }, { 122.1, 122.2 } };
void fa_s1(struct s1 a) { printf("%.1s\n", a.x); }
void fa_s2(struct s2 a) { printf("%.2s\n", a.x); }
void fa_s3(struct s3 a) { printf("%.3s\n", a.x); }
@ -82,6 +87,10 @@ void fa_hfa33(struct hfa33 a)
{ printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); }
void fa_hfa34(struct hfa34 a)
{ printf("%.1Lf %.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c, a.d); }
void fa_hfae12(struct hfae12 a)
{ printf("%.1f %.1f\n", a.h.a, a.h.b); }
void fa_hfae22(struct hfae22 a)
{ printf("%.1f %.1f\n", a.h.a, a.h.b); }
void fa1(struct s8 a, struct s9 b, struct s10 c, struct s11 d,
struct s12 e, struct s13 f)
@ -140,6 +149,8 @@ void arg(void)
fa_hfa32(hfa32);
fa_hfa33(hfa33);
fa_hfa34(hfa34);
fa_hfae12(hfae12);
fa_hfae22(hfae22);
fa1(s8, s9, s10, s11, s12, s13);
fa2(s9, s10, s11, s12, s13, s14);
fa3(hfa14, hfa23, hfa32);
@ -178,6 +189,8 @@ struct hfa31 fr_hfa31(void) { return hfa31; }
struct hfa32 fr_hfa32(void) { return hfa32; }
struct hfa33 fr_hfa33(void) { return hfa33; }
struct hfa34 fr_hfa34(void) { return hfa34; }
struct hfae12 fr_hfae12(void) { return hfae12; }
struct hfae22 fr_hfae22(void) { return hfae22; }
void ret(void)
{
@ -228,6 +241,8 @@ void ret(void)
printf("%.1Lf %.1Lf\n", fr_hfa32().a, fr_hfa32().b);
printf("%.1Lf %.1Lf\n", fr_hfa33().a, fr_hfa33().c);
printf("%.1Lf %.1Lf\n", fr_hfa34().a, fr_hfa34().d);
printf("%.1f %.1f\n", fr_hfae12().h.a, fr_hfae12().h.b);
printf("%.1f %.1f\n", fr_hfae22().h.a, fr_hfae22().h.b);
}
void*

View File

@ -28,6 +28,8 @@ cdefghijklmnopqrs
32.1 32.1
33.1 33.2 33.3
34.1 34.2 34.3 34.4
112.1 112.2
122.1 122.2
stu ABC JKL TUV 456 ghi
ABC JKL TUV 456 ghi tuv
14.1 14.4 23.1 23.3 32.1 32.2
@ -62,6 +64,8 @@ cdefghijklmnopqrs
32.1 32.2
33.1 33.3
34.1 34.4
112.1 112.2
122.1 122.2
stdarg:
ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI
lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI