From 13471741b538baa45cd53a521cf7d52087f3200f Mon Sep 17 00:00:00 2001 From: lemon Date: Wed, 5 Nov 2025 13:56:54 +0100 Subject: amd64: fix aggregate abi stuff;; ir: fold, peephole optimizing constructors --- amd64/isel.c | 3 +-- amd64/sysv.c | 44 +++++++++++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 19 deletions(-) (limited to 'amd64') diff --git a/amd64/isel.c b/amd64/isel.c index 133868e..c250ec0 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -137,7 +137,6 @@ selcall(struct function *fn, struct instr *ins, struct block *blk, int *curi) } #define isimm32(r) (concls(r) == KI4) -#define rswap(a,b) do { union ref _t = (a); (a) = (b); (b) = _t; } while (0) static bool acon(struct addr *addr, union ref r) @@ -248,7 +247,7 @@ fuseaddr(union ref *r, struct block *blk, int *curi) if (!addr.base.bits) { /* absolute int address in disp */ - assert(!addr.index.bits); + if (addr.index.bits) return 0; addr.base = mkintcon(KPTR, addr.disp); addr.disp = 0; } diff --git a/amd64/sysv.c b/amd64/sysv.c index 43ecd3c..334be26 100644 --- a/amd64/sysv.c +++ b/amd64/sysv.c @@ -1,6 +1,24 @@ #include "all.h" static int classify(uchar cls[2], const struct typedata *td, uint off); + +static void +clsscalar(uchar cls[2], uint off, union type ty) +{ + enum irclass k = type2cls[scalartypet(ty)]; + uchar *fcls = &cls[off/8]; + if (isflt(ty)) { /* SSE */ + if (!*fcls || (*fcls == KF4 && k > *fcls)) + *fcls = k; + } else { /* INTEGER */ + assert(isint(ty) || ty.t == TYPTR); + if (cls2siz[*fcls] < cls2siz[k]) + *fcls = k; + } + if (off % 8 >= 4 && cls2siz[*fcls] < 8) + *fcls = kisint(*fcls) ? KI8 : KF8; +} + static int classifyarr(uchar cls[2], union type ty, uint off) { @@ -15,12 +33,8 @@ classifyarr(uchar cls[2], union type ty, uint off) } else if (chld.t == TYARRAY) { if (!classifyarr(cls, chld, offx)) return cls[0] = cls[1] = 0; - } else if (isflt(chld)) { /* SSE */ - if (!cls[offx/8]) - cls[offx/8] = KF8; - } else { /* INTEGER */ - assert(isint(chld) || chld.t == TYPTR); - cls[offx/8] = KI8; + } else { + clsscalar(cls, offx, chld); } } return !!cls[0] + !!cls[1]; @@ -28,7 +42,7 @@ classifyarr(uchar cls[2], union type ty, uint off) static int classify(uchar cls[2], const struct typedata *td, uint off) { - uint siz = alignup(td->siz, 8); + uint siz = alignup(td->siz, 4); if (siz > 16) /* MEMORY */ return 0; for (int i = 0; i < td->nmemb; ++i) { @@ -43,12 +57,8 @@ classify(uchar cls[2], const struct typedata *td, uint off) if (isincomplete(fld->t)) continue; if (!classifyarr(cls, fld->t, off + fld->off)) return cls[0] = cls[1] = 0; - } else if (isflt(fld->t)) { /* SSE */ - if (!cls[(fld->off + off)/8]) - cls[(fld->off + off)/8] = KF8; - } else { /* INTEGER */ - assert(isint(fld->t) || fld->t.t == TYPTR); - cls[(fld->off + off)/8] = KI8; + } else { + clsscalar(cls, fld->off + off, fld->t); } } return !!cls[0] + !!cls[1]; @@ -84,9 +94,9 @@ abiarg(short r[2], uchar cls[2], int *ni, int *nf, int *ns, union irtype typ) ni_save = *ni, nf_save = *nf; for (int i = 0; i < ret; ++i) { assert(cls[i]); - if (cls[i] == KF8 && *nf < NFLT) + if (kisflt(cls[i]) && *nf < NFLT) r[i] = XMM0 + (*nf)++; - else if (cls[i] == KI8 && *ni < NINT) + else if (kisint(cls[i]) && *ni < NINT) r[i] = intregs[(*ni)++]; else { /* MEMORY */ *ni = ni_save, *nf = nf_save; @@ -121,9 +131,9 @@ abiret(short r[2], uchar cls[2], int *ni, union irtype typ) assert(ret <= 2); for (int i = 0, ni = 0, nf = 0; i < ret; ++i) { assert(cls[i]); - if (cls[i] == KF8) /* SSE (XMM0, XMM1) */ + if (kisflt(cls[i])) /* SSE (XMM0, XMM1) */ r[i] = XMM0 + nf++; - else if (cls[i] == KI8) /* INTEGER (RAX, RDX) */ + else if (kisint(cls[i])) /* INTEGER (RAX, RDX) */ r[i] = ni++ == 0 ? RAX : RDX; else assert(0); } -- cgit v1.2.3