|
@@ -17,11 +17,44 @@ struct RAlloc {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
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;
|
|
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;
|
|
sz = t->size;
|
|
|
al = 1u << t->align;
|
|
al = 1u << t->align;
|
|
@@ -46,31 +79,12 @@ aclass(AClass *a, Typ *t)
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- seg = t->seg[0];
|
|
|
|
|
|
|
+ a->cls[0] = Kx;
|
|
|
|
|
+ a->cls[1] = Kx;
|
|
|
a->inmem = 0;
|
|
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
|
|
static void
|
|
@@ -124,7 +138,7 @@ selret(Blk *b, Fn *fn)
|
|
|
b->jmp.type = Jret0;
|
|
b->jmp.type = Jret0;
|
|
|
|
|
|
|
|
if (j == Jretc) {
|
|
if (j == Jretc) {
|
|
|
- aclass(&aret, &typ[fn->retty]);
|
|
|
|
|
|
|
+ typclass(&aret, &typ[fn->retty]);
|
|
|
if (aret.inmem) {
|
|
if (aret.inmem) {
|
|
|
assert(rtype(fn->retr) == RTmp);
|
|
assert(rtype(fn->retr) == RTmp);
|
|
|
emit(Ocopy, Kl, TMP(RAX), fn->retr, R);
|
|
emit(Ocopy, Kl, TMP(RAX), fn->retr, R);
|
|
@@ -154,7 +168,7 @@ selret(Blk *b, Fn *fn)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
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;
|
|
int nint, ni, nsse, ns, n, *pn;
|
|
|
AClass *a;
|
|
AClass *a;
|
|
@@ -181,7 +195,7 @@ classify(Ins *i0, Ins *i1, AClass *ac, int op, AClass *aret)
|
|
|
a->cls[0] = i->cls;
|
|
a->cls[0] = i->cls;
|
|
|
} else {
|
|
} else {
|
|
|
n = i->arg[0].val;
|
|
n = i->arg[0].val;
|
|
|
- aclass(a, &typ[n]);
|
|
|
|
|
|
|
+ typclass(a, &typ[n]);
|
|
|
if (a->inmem)
|
|
if (a->inmem)
|
|
|
continue;
|
|
continue;
|
|
|
ni = ns = 0;
|
|
ni = ns = 0;
|
|
@@ -279,10 +293,10 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
|
|
|
ac = alloc((i1-i0) * sizeof ac[0]);
|
|
ac = alloc((i1-i0) * sizeof ac[0]);
|
|
|
if (!req(i1->arg[1], R)) {
|
|
if (!req(i1->arg[1], R)) {
|
|
|
assert(rtype(i1->arg[1]) == RType);
|
|
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
|
|
} else
|
|
|
- ca = classify(i0, i1, ac, Oarg, 0);
|
|
|
|
|
|
|
+ ca = argsclass(i0, i1, ac, Oarg, 0);
|
|
|
|
|
|
|
|
for (stk=0, a=&ac[i1-i0]; a>ac;)
|
|
for (stk=0, a=&ac[i1-i0]; a>ac;)
|
|
|
if ((--a)->inmem) {
|
|
if ((--a)->inmem) {
|
|
@@ -393,10 +407,10 @@ selpar(Fn *fn, Ins *i0, Ins *i1)
|
|
|
ni = ns = 0;
|
|
ni = ns = 0;
|
|
|
|
|
|
|
|
if (fn->retty >= 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
|
|
} else
|
|
|
- classify(i0, i1, ac, Opar, 0);
|
|
|
|
|
|
|
+ argsclass(i0, i1, ac, Opar, 0);
|
|
|
|
|
|
|
|
for (i=i0, a=ac; i<i1; i++, a++) {
|
|
for (i=i0, a=ac; i<i1; i++, a++) {
|
|
|
if (i->op != Oparc || a->inmem)
|
|
if (i->op != Oparc || a->inmem)
|