qbe

Internal scc patchset buffer for QBE
Log | Files | Refs | README | LICENSE

commit 9060981c10c21834596d5677a2c9ccc56809eb64
parent 349794f3e4f11e4cc34a501ba935a2a305229738
Author: Quentin Carbonneaux <quentin@c9x.me>
Date:   Tue,  8 Mar 2022 15:49:01 +0100

flag types defined as unions

The risc-v abi needs to know if a
type is defined as a union or not.

We cannot use nunion to obtain this
information because the risc-v abi
made the unfortunate decision of
treating

	union { int i; }

differently from

	int i;

So, instead, I introduce a single
bit flag 'isunion'.

Diffstat:
Mall.h | 3++-
Mamd64/sysv.c | 2+-
Marm64/abi.c | 2+-
Mparse.c | 10++++++----
Mrv64/abi.c | 2+-
5 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/all.h b/all.h @@ -357,7 +357,8 @@ struct Fn { struct Typ { char name[NString]; - int dark; + char isdark; + char isunion; int align; uint64_t size; uint nunion; diff --git a/amd64/sysv.c b/amd64/sysv.c @@ -77,7 +77,7 @@ typclass(AClass *a, Typ *t) a->size = sz; a->align = t->align; - if (t->dark || sz > 16 || sz == 0) { + if (t->isdark || sz > 16 || sz == 0) { /* large or unaligned structures are * required to be passed in memory */ diff --git a/arm64/abi.c b/arm64/abi.c @@ -94,7 +94,7 @@ typclass(Class *c, Typ *t, int *gp, int *fp) if (t->align > 4) err("alignments larger than 16 are not supported"); - if (t->dark || sz > 16 || sz == 0) { + if (t->isdark || sz > 16 || sz == 0) { /* large structs are replaced by a * pointer to some caller-allocated * memory */ diff --git a/parse.c b/parse.c @@ -925,7 +925,8 @@ parsetyp() */ vgrow(&typ, ntyp+1); ty = &typ[ntyp++]; - ty->dark = 0; + ty->isdark = 0; + ty->isunion = 0; ty->align = -1; ty->size = 0; if (nextnl() != Ttyp || nextnl() != Teq) @@ -944,7 +945,7 @@ parsetyp() err("type body must start with {"); t = nextnl(); if (t == Tint) { - ty->dark = 1; + ty->isdark = 1; ty->size = tokval.num; if (ty->align == -1) err("dark types need alignment"); @@ -954,7 +955,8 @@ parsetyp() } n = 0; ty->fields = vnew(1, sizeof ty->fields[0], Pheap); - if (t == Tlbrace) + if (t == Tlbrace) { + ty->isunion = 1; do { if (t != Tlbrace) err("invalid union member"); @@ -962,7 +964,7 @@ parsetyp() parsefields(ty->fields[n++], ty, nextnl()); t = nextnl(); } while (t != Trbrace); - else + } else parsefields(ty->fields[n++], ty, t); ty->nunion = n; } diff --git a/rv64/abi.c b/rv64/abi.c @@ -105,7 +105,7 @@ typclass(Class *c, Typ *t, int *gp, int *fp) if (t->align > 4) err("alignments larger than 16 are not supported"); - if (t->dark || sz > 16 || sz == 0) { + if (t->isdark || sz > 16 || sz == 0) { /* large structs are replaced by a * pointer to some caller-allocated * memory */