diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-04-03 21:47:37 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-04-03 21:47:37 -0400 |
commit | ecb2fe88dca4b3c6b695451373d71eed0aeb7830 (patch) | |
tree | aae375c7055aa9209fa62005e7902048dc5dada5 /sysv.c | |
parent | ba2e93b124e1e0d83d4ec4197df514a964917c9c (diff) | |
download | roux-ecb2fe88dca4b3c6b695451373d71eed0aeb7830.tar.gz |
rewrite of selpar() for factoring
Diffstat (limited to 'sysv.c')
-rw-r--r-- | sysv.c | 87 |
1 files changed, 82 insertions, 5 deletions
diff --git a/sysv.c b/sysv.c index 2a6dee2..cd2e97e 100644 --- a/sysv.c +++ b/sysv.c @@ -8,6 +8,12 @@ struct AClass { int align; uint size; int cls[2]; + Ref ref[2]; +}; + +struct RAlloc { + Ins i; + RAlloc *link; }; static void @@ -252,11 +258,6 @@ rarg(int ty, int *ni, int *ns) return TMP(XMM0 + (*ns)++); } -struct RAlloc { - Ins i; - RAlloc *link; -}; - static void selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap) { @@ -378,6 +379,72 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap) } static void +selpar_(Fn *fn, Ins *i0, Ins *i1) +{ + AClass *ac, *a, aret; + Ins *i; + int ni, ns, s, al; + Ref r; + + ac = alloc((i1-i0) * sizeof ac[0]); + curi = &insb[NIns]; + ni = ns = 0; + + if (fn->retty >= 0) { + aclass(&aret, &typ[fn->retty]); + classify(i0, i1, ac, OPar, &aret); + } else + classify(i0, i1, ac, OPar, 0); + + for (i=i0, a=ac; i<i1; i++, a++) { + if (i->op != OParc || a->inmem) + continue; + for (al=0; a->align >> (al+2); al++) /* CHECK IF NOT STUPID */ + ; + if (a->size > 8) { + r = newtmp("abi", Kl, fn); + a->ref[1] = newtmp("abi", Kl, fn); + emit(OStorel, 0, R, a->ref[1], r); + emit(OAdd, Kl, r, i->to, getcon(8, fn)); + } + a->ref[0] = newtmp("abi", Kl, fn); + emit(OStorel, 0, R, a->ref[0], i->to); + emit(OAlloc+al, Kl, i->to, getcon(a->size, fn), R); + } + + if (fn->retty >= 0 && aret.inmem) { + r = newtmp("abi", Kl, fn); + emit(OCopy, Kl, r, rarg(Kl, &ni, &ns), R); + fn->retr = r; + } + + for (i=i0, a=ac, s=4; i<i1; i++, a++) { + switch (a->inmem) { + case 1: + assert(a->align <= 4); + if (a->align == 4) + s = (s+3) & -4; + fn->tmp[i->to.val].slot = -s; + s += a->size / 4; + continue; + case 2: + emit(OLoad, i->cls, i->to, SLOT(-s), R); + s += 2; + continue; + } + r = rarg(a->cls[0], &ni, &ns); + if (i->op == OParc) { + emit(OCopy, Kl, a->ref[0], r, R); + if (a->size > 8) { + r = rarg(a->cls[1], &ni, &ns); + emit(OCopy, Kl, a->ref[1], r, R); + } + } else + emit(OCopy, i->cls, i->to, r, R); + } +} + +static void selpar(Fn *fn, Ins *i0, Ins *i1) { AClass *ac, *a, aret; @@ -461,6 +528,7 @@ abi(Fn *fn) for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++) if (i->op != OPar && i->op != OParc) break; +#if 0 selpar(fn, b->ins, i); n = b->nins - (i - b->ins) + (curi - insb); i0 = alloc(n * sizeof(Ins)); @@ -468,6 +536,15 @@ abi(Fn *fn) ip = icpy(ip, i, &b->ins[b->nins] - i); b->nins = n; b->ins = i0; +#else + selpar_(fn, b->ins, i); + n = b->nins - (i - b->ins) + (&insb[NIns] - curi); + i0 = alloc(n * sizeof(Ins)); + ip = icpy(ip = i0, curi, &insb[NIns] - curi); + ip = icpy(ip, i, &b->ins[b->nins] - i); + b->nins = n; + b->ins = i0; +#endif /* lower calls and returns */ ral = 0; |