summaryrefslogtreecommitdiff
path: root/6/isel.c
diff options
context:
space:
mode:
Diffstat (limited to '6/isel.c')
-rw-r--r--6/isel.c175
1 files changed, 78 insertions, 97 deletions
diff --git a/6/isel.c b/6/isel.c
index 8f682a5..0000424 100644
--- a/6/isel.c
+++ b/6/isel.c
@@ -611,34 +611,18 @@ placearg(Isel *s, Node *argn, Loc *argloc, PassIn p, Loc *rsp, int vararg, size_
static int
sufficientregs(ArgType a, size_t nfloats, size_t nints)
{
- size_t needed_ints = 0;
- size_t needed_flts = 0;
-
- switch(a) {
- case ArgSmallAggr_Int:
- case ArgSmallAggr_Flt_Int:
- case ArgSmallAggr_Int_Flt:
- needed_ints = 1;
- break;
- case ArgSmallAggr_Int_Int:
- needed_ints = 2;
- break;
- default: break;
- }
-
- switch(a) {
- case ArgSmallAggr_Flt:
- case ArgSmallAggr_Flt_Int:
- case ArgSmallAggr_Int_Flt:
- needed_flts = 1;
- break;
- case ArgSmallAggr_Flt_Flt:
- needed_flts = 2;
- break;
- default: break;
- }
-
- return (needed_flts + nfloats <= Nfloatregargs) && (needed_ints + nints <= Nintregargs);
+ static const struct {
+ int ireg;
+ int freg;
+ } needed[] = {
+ [ArgAggrI] = {1, 0},
+ [ArgAggrFI] = {1, 1},
+ [ArgAggrIF] = {1, 1},
+ [ArgAggrII] = {2, 0},
+ [ArgAggrFF] = {0, 2},
+ };
+
+ return (needed[a].freg + nfloats <= Nfloatregargs) && (needed[a].ireg + nints <= Nintregargs);
}
static Loc *
@@ -661,7 +645,7 @@ gencall(Isel *s, Node *n)
size_t nfloats, nints;
Loc *retloc1, *retloc2, *rsp; /* hard-coded registers */
Loc *ret;
- size_t nextintretreg = 0, nextfltretreg = 0;
+ size_t ri, rf;
Loc *stkbump; /* calculated stack offset */
Type *t, *fn;
Node **args;
@@ -673,6 +657,8 @@ gencall(Isel *s, Node *n)
rsp = locphysreg(Rrsp);
t = exprtype(n);
+ ri = 0;
+ rf = 0;
retloc1 = NULL;
retloc2 = NULL;
rettype = classify(t);
@@ -682,33 +668,29 @@ gencall(Isel *s, Node *n)
case ArgBig:
break;
case ArgReg:
- if (istyfloat(t)) {
- retloc1 = coreg(Rxmm0d, mode(n));
- } else {
- retloc1 = coreg(Rrax, mode(n));
- }
+ retloc1 = coreg((istyfloat(t)) ? Rxmm0d : Rrax, mode(n));
break;
- case ArgSmallAggr_Int:
- retloc1 = coreg(intretregs[nextintretreg++], tymodepart(t, 0, 0));
+ case ArgAggrI:
+ retloc1 = coreg(intretregs[ri++], tymodepart(t, 0, 0));
break;
- case ArgSmallAggr_Flt:
- retloc1 = coreg(fltretregs[nextfltretreg++], tymodepart(t, 1, 0));
+ case ArgAggrF:
+ retloc1 = coreg(fltretregs[rf++], tymodepart(t, 1, 0));
break;
- case ArgSmallAggr_Int_Int:
- retloc1 = coreg(intretregs[nextintretreg++], tymodepart(t, 0, 0));
- retloc2 = coreg(intretregs[nextintretreg++], tymodepart(t, 0, 8));
+ case ArgAggrII:
+ retloc1 = coreg(intretregs[ri++], tymodepart(t, 0, 0));
+ retloc2 = coreg(intretregs[ri++], tymodepart(t, 0, 8));
break;
- case ArgSmallAggr_Int_Flt:
- retloc1 = coreg(intretregs[nextintretreg++], tymodepart(t, 0, 0));
- retloc2 = coreg(fltretregs[nextfltretreg++], tymodepart(t, 1, 8));
+ case ArgAggrIF:
+ retloc1 = coreg(intretregs[ri++], tymodepart(t, 0, 0));
+ retloc2 = coreg(fltretregs[rf++], tymodepart(t, 1, 8));
break;
- case ArgSmallAggr_Flt_Int:
- retloc1 = coreg(fltretregs[nextfltretreg++], tymodepart(t, 1, 0));
- retloc2 = coreg(intretregs[nextintretreg++], tymodepart(t, 0, 8));
+ case ArgAggrFI:
+ retloc1 = coreg(fltretregs[rf++], tymodepart(t, 1, 0));
+ retloc2 = coreg(intretregs[ri++], tymodepart(t, 0, 8));
break;
- case ArgSmallAggr_Flt_Flt:
- retloc1 = coreg(fltretregs[nextfltretreg++], tymodepart(t, 1, 0));
- retloc2 = coreg(fltretregs[nextfltretreg++], tymodepart(t, 1, 8));
+ case ArgAggrFF:
+ retloc1 = coreg(fltretregs[rf++], tymodepart(t, 1, 0));
+ retloc2 = coreg(fltretregs[rf++], tymodepart(t, 1, 8));
break;
}
@@ -785,25 +767,25 @@ gencall(Isel *s, Node *n)
/* placearg can figure this out */
placearg(s, args[i], arg, PassInNoPref, rsp, vararg, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Int:
+ case ArgAggrI:
placearg(s, args[i], arg, PassInInt, rsp, vararg, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Flt:
+ case ArgAggrF:
placearg(s, args[i], arg, PassInSSE, rsp, vararg, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Int_Int:
+ case ArgAggrII:
placearg(s, args[i], arg , PassInInt, rsp, vararg, &nfloats, &nints, &argoff);
placearg(s, args[i], plus8(s, arg), PassInInt, rsp, vararg, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Int_Flt:
+ case ArgAggrIF:
placearg(s, args[i], arg , PassInInt, rsp, vararg, &nfloats, &nints, &argoff);
placearg(s, args[i], plus8(s, arg), PassInSSE, rsp, vararg, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Flt_Int:
+ case ArgAggrFI:
placearg(s, args[i], arg , PassInSSE, rsp, vararg, &nfloats, &nints, &argoff);
placearg(s, args[i], plus8(s, arg), PassInInt, rsp, vararg, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Flt_Flt:
+ case ArgAggrFF:
placearg(s, args[i], arg , PassInSSE, rsp, vararg, &nfloats, &nints, &argoff);
placearg(s, args[i], plus8(s, arg), PassInSSE, rsp, vararg, &nfloats, &nints, &argoff);
break;
@@ -830,25 +812,25 @@ gencall(Isel *s, Node *n)
else
g(s, Imov, retloc1, ret, NULL);
break;
- case ArgSmallAggr_Int:
+ case ArgAggrI:
g(s, Imov, retloc1, locmem(0, inri(s, selexpr(s, retnode)), NULL, ModeQ), NULL);
break;
- case ArgSmallAggr_Flt:
+ case ArgAggrF:
g(s, Imovs, retloc1, locmem(0, inri(s, selexpr(s, retnode)), NULL, ModeD), NULL);
break;
- case ArgSmallAggr_Int_Int:
+ case ArgAggrII:
g(s, Imov, retloc1, locmem(0, inri(s, selexpr(s, retnode)), NULL, ModeQ), NULL);
g(s, Imov, retloc2, locmem(8, inri(s, selexpr(s, retnode)), NULL, ModeQ), NULL);
break;
- case ArgSmallAggr_Int_Flt:
+ case ArgAggrIF:
g(s, Imov, retloc1, locmem(0, inri(s, selexpr(s, retnode)), NULL, ModeQ), NULL);
g(s, Imovs, retloc2, locmem(8, inri(s, selexpr(s, retnode)), NULL, ModeD), NULL);
break;
- case ArgSmallAggr_Flt_Int:
+ case ArgAggrFI:
g(s, Imovs, retloc1, locmem(0, inri(s, selexpr(s, retnode)), NULL, ModeD), NULL);
g(s, Imov, retloc2, locmem(8, inri(s, selexpr(s, retnode)), NULL, ModeQ), NULL);
break;
- case ArgSmallAggr_Flt_Flt:
+ case ArgAggrFF:
g(s, Imovs, retloc1, locmem(0, inri(s, selexpr(s, retnode)), NULL, ModeD), NULL);
g(s, Imovs, retloc2, locmem(8, inri(s, selexpr(s, retnode)), NULL, ModeD), NULL);
break;
@@ -1307,30 +1289,30 @@ addarglocs(Isel *s, Func *fn)
/* retrievearg can figure this out */
retrievearg(s, arg, vararg, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Int:
+ case ArgAggrI:
l = loc(s, arg);
movearg(s, l, PassInInt, ModeQ, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Flt:
+ case ArgAggrF:
l = loc(s, arg);
movearg(s, l, PassInSSE, ModeD, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Int_Int:
+ case ArgAggrII:
l = loc(s, arg);
movearg(s, l , PassInInt, ModeQ, &nfloats, &nints, &argoff);
movearg(s, plus8(s, l), PassInInt, ModeQ, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Int_Flt:
+ case ArgAggrIF:
l = loc(s, arg);
movearg(s, l , PassInInt, ModeQ, &nfloats, &nints, &argoff);
movearg(s, plus8(s, l), PassInSSE, ModeD, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Flt_Int:
+ case ArgAggrFI:
l = loc(s, arg);
movearg(s, l , PassInSSE, ModeD, &nfloats, &nints, &argoff);
movearg(s, plus8(s, l), PassInInt, ModeQ, &nfloats, &nints, &argoff);
break;
- case ArgSmallAggr_Flt_Flt:
+ case ArgAggrFF:
l = loc(s, arg);
movearg(s, l , PassInSSE, ModeD, &nfloats, &nints, &argoff);
movearg(s, plus8(s, l), PassInSSE, ModeD, &nfloats, &nints, &argoff);
@@ -1378,12 +1360,13 @@ epilogue(Isel *s)
Loc *rsp, *rbp;
Loc *ret;
size_t i;
- size_t nextintretreg = 0, nextfltretreg = 0;
+ size_t ri = 0, rf = 0;
rsp = locphysreg(Rrsp);
rbp = locphysreg(Rrbp);
switch (s->rettype) {
- case ArgVoid: break;
+ case ArgVoid:
+ break;
case ArgReg:
/* s->ret is a value, and will be returned that way */
ret = loc(s, s->ret);
@@ -1397,45 +1380,43 @@ epilogue(Isel *s)
ret = loc(s, s->ret);
g(s, Imov, ret, coreg(Rax, ret->mode), NULL);
break;
- case ArgSmallAggr_Int:
+ case ArgAggrI:
/* s->ret is an address, and will be returned as values */
ret = loc(s, s->ret);
- load(s, locmem(0, ret, NULL, ModeQ), coreg(intretregs[nextintretreg++], ModeQ));
+ load(s, locmem(0, ret, NULL, ModeQ), coreg(intretregs[ri++], ModeQ));
break;
- case ArgSmallAggr_Flt:
+ case ArgAggrF:
ret = loc(s, s->ret);
- load(s, locmem(0, ret, NULL, ModeD), coreg(fltretregs[nextfltretreg++], ModeD));
+ load(s, locmem(0, ret, NULL, ModeD), coreg(fltretregs[rf++], ModeD));
break;
- case ArgSmallAggr_Int_Int:
+ case ArgAggrII:
ret = loc(s, s->ret);
- load(s, locmem(0, ret, NULL, ModeQ), coreg(intretregs[nextintretreg++], ModeQ));
- load(s, locmem(8, ret, NULL, ModeQ), coreg(intretregs[nextintretreg++], ModeQ));
+ load(s, locmem(0, ret, NULL, ModeQ), coreg(intretregs[ri++], ModeQ));
+ load(s, locmem(8, ret, NULL, ModeQ), coreg(intretregs[ri++], ModeQ));
break;
- case ArgSmallAggr_Int_Flt:
+ case ArgAggrIF:
ret = loc(s, s->ret);
- load(s, locmem(0, ret, NULL, ModeQ), coreg(intretregs[nextintretreg++], ModeQ));
- load(s, locmem(8, ret, NULL, ModeD), coreg(fltretregs[nextfltretreg++], ModeD));
+ load(s, locmem(0, ret, NULL, ModeQ), coreg(intretregs[ri++], ModeQ));
+ load(s, locmem(8, ret, NULL, ModeD), coreg(fltretregs[rf++], ModeD));
break;
- case ArgSmallAggr_Flt_Int:
+ case ArgAggrFI:
ret = loc(s, s->ret);
- load(s, locmem(0, ret, NULL, ModeD), coreg(fltretregs[nextfltretreg++], ModeD));
- load(s, locmem(8, ret, NULL, ModeQ), coreg(intretregs[nextintretreg++], ModeQ));
+ load(s, locmem(0, ret, NULL, ModeD), coreg(fltretregs[rf++], ModeD));
+ load(s, locmem(8, ret, NULL, ModeQ), coreg(intretregs[ri++], ModeQ));
break;
- case ArgSmallAggr_Flt_Flt:
+ case ArgAggrFF:
ret = loc(s, s->ret);
- load(s, locmem(0, ret, NULL, ModeD), coreg(fltretregs[nextfltretreg++], ModeD));
- load(s, locmem(8, ret, NULL, ModeD), coreg(fltretregs[nextfltretreg++], ModeD));
+ load(s, locmem(0, ret, NULL, ModeD), coreg(fltretregs[rf++], ModeD));
+ load(s, locmem(8, ret, NULL, ModeD), coreg(fltretregs[rf++], ModeD));
break;
}
/* restore registers */
- for (i = 0; savedregs[i] != Rnone; i++) {
- if (isfloatmode(s->calleesave[i]->mode)) {
+ for (i = 0; savedregs[i] != Rnone; i++)
+ if (isfloatmode(s->calleesave[i]->mode))
g(s, Imovs, s->calleesave[i], locphysreg(savedregs[i]), NULL);
- } else {
+ else
g(s, Imov, s->calleesave[i], locphysreg(savedregs[i]), NULL);
- }
- }
/* leave function */
g(s, Imov, rbp, rsp, NULL);
g(s, Ipop, rbp, NULL);
@@ -1490,16 +1471,16 @@ handlesmallstructargs(Isel *is, Func *fn)
case ArgBig:
/* No need for any extra space for this arg */
break;
- case ArgSmallAggr_Int:
- case ArgSmallAggr_Flt:
+ case ArgAggrI:
+ case ArgAggrF:
fn->stksz += 8;
fn->stksz = align(fn->stksz, min(8, Ptrsz));
htput(fn->stkoff, fn->args[i], itop(fn->stksz));
break;
- case ArgSmallAggr_Int_Int:
- case ArgSmallAggr_Int_Flt:
- case ArgSmallAggr_Flt_Int:
- case ArgSmallAggr_Flt_Flt:
+ case ArgAggrII:
+ case ArgAggrIF:
+ case ArgAggrFI:
+ case ArgAggrFF:
fn->stksz += 16;
fn->stksz = align(fn->stksz, min(16, Ptrsz));
htput(fn->stkoff, fn->args[i], itop(fn->stksz));