diff options
Diffstat (limited to 'sysv.c')
-rw-r--r-- | sysv.c | 86 |
1 files changed, 50 insertions, 36 deletions
diff --git a/sysv.c b/sysv.c index 7e5b819..5a82f8e 100644 --- a/sysv.c +++ b/sysv.c @@ -17,11 +17,44 @@ struct RAlloc { }; static void -aclass(AClass *a, Typ *t) +classify(AClass *a, Typ *t, int *pn, int *pe) { - int e, s, n, cls; - uint sz, al; Seg *seg; + int n, s, *cls; + + for (n=0; n<t->nunion; n++) { + seg = t->seg[n]; + for (s=0; *pe<2; (*pe)++) { + cls = &a->cls[*pe]; + for (; *pn<8 && seg[s].type!=Send; s++) { + switch (seg[s].type) { + case Spad: + /* don't change anything */ + break; + case Sflt: + if (*cls == Kx) + *cls = Kd; + break; + case Sint: + *cls = Kl; + break; + case Styp: + classify(a, &typ[seg[s].len], pn, pe); + continue; + } + *pn += seg[s].len; + } + assert(*pn <= 8); + *pn = 0; + } + } +} + +static void +typclass(AClass *a, Typ *t) +{ + int e, n; + uint sz, al; sz = t->size; al = 1u << t->align; @@ -46,31 +79,12 @@ aclass(AClass *a, Typ *t) return; } - seg = t->seg[0]; + a->cls[0] = Kx; + a->cls[1] = Kx; a->inmem = 0; - for (e=0, s=0; e<2; e++) { - cls = -1; - for (n=0; n<8 && seg[s].len; s++) { - switch (seg[s].type) { - case Spad: - /* don't change anything */ - break; - case Sflt: - if (cls == -1) - cls = Kd; - break; - case Sint: - cls = Kl; - break; - case Styp: - assert(!"todo"); - break; - } - n += seg[s].len; - } - assert(n <= 8); - a->cls[e] = cls; - } + n = 0; + e = 0; + classify(a, t, &n, &e); } static void @@ -124,7 +138,7 @@ selret(Blk *b, Fn *fn) b->jmp.type = Jret0; if (j == Jretc) { - aclass(&aret, &typ[fn->retty]); + typclass(&aret, &typ[fn->retty]); if (aret.inmem) { assert(rtype(fn->retr) == RTmp); emit(Ocopy, Kl, TMP(RAX), fn->retr, R); @@ -154,7 +168,7 @@ selret(Blk *b, Fn *fn) } static int -classify(Ins *i0, Ins *i1, AClass *ac, int op, AClass *aret) +argsclass(Ins *i0, Ins *i1, AClass *ac, int op, AClass *aret) { int nint, ni, nsse, ns, n, *pn; AClass *a; @@ -181,7 +195,7 @@ classify(Ins *i0, Ins *i1, AClass *ac, int op, AClass *aret) a->cls[0] = i->cls; } else { n = i->arg[0].val; - aclass(a, &typ[n]); + typclass(a, &typ[n]); if (a->inmem) continue; ni = ns = 0; @@ -279,10 +293,10 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap) ac = alloc((i1-i0) * sizeof ac[0]); if (!req(i1->arg[1], R)) { assert(rtype(i1->arg[1]) == RType); - aclass(&aret, &typ[i1->arg[1].val]); - ca = classify(i0, i1, ac, Oarg, &aret); + typclass(&aret, &typ[i1->arg[1].val]); + ca = argsclass(i0, i1, ac, Oarg, &aret); } else - ca = classify(i0, i1, ac, Oarg, 0); + ca = argsclass(i0, i1, ac, Oarg, 0); for (stk=0, a=&ac[i1-i0]; a>ac;) if ((--a)->inmem) { @@ -393,10 +407,10 @@ selpar(Fn *fn, Ins *i0, Ins *i1) ni = ns = 0; if (fn->retty >= 0) { - aclass(&aret, &typ[fn->retty]); - classify(i0, i1, ac, Opar, &aret); + typclass(&aret, &typ[fn->retty]); + argsclass(i0, i1, ac, Opar, &aret); } else - classify(i0, i1, ac, Opar, 0); + argsclass(i0, i1, ac, Opar, 0); for (i=i0, a=ac; i<i1; i++, a++) { if (i->op != Oparc || a->inmem) |