aboutsummaryrefslogtreecommitdiff
path: root/amd64/isel.c
diff options
context:
space:
mode:
authorQuentin Carbonneaux <[email protected]>2026-01-13 18:11:07 +0100
committerQuentin Carbonneaux <[email protected]>2026-01-13 18:11:37 +0100
commitc6336557dad1161088c3f60a8045d676fb924ed5 (patch)
treed82f530fe255b1ee9219cca79b1cbb4eb311af31 /amd64/isel.c
parent5c1eb24e2c312021c7af4316e5adde53e270311a (diff)
ifopt simplifications
Diffstat (limited to 'amd64/isel.c')
-rw-r--r--amd64/isel.c81
1 files changed, 37 insertions, 44 deletions
diff --git a/amd64/isel.c b/amd64/isel.c
index c54b580..73e0860 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -429,25 +429,8 @@ sel(Ins i, Num *tn, Fn *fn)
case Oexts:
case Otruncd:
case Ocast:
- case Oxselieq:
- case Oxseline:
- case Oxselisge:
- case Oxselisgt:
- case Oxselisle:
- case Oxselislt:
- case Oxseliuge:
- case Oxseliugt:
- case Oxseliule:
- case Oxseliult:
- case Oxselfeq:
- case Oxselfge:
- case Oxselfgt:
- case Oxselfle:
- case Oxselflt:
- case Oxselfne:
- case Oxselfo:
- case Oxselfuo:
- case_OExt:
+ case_Oxsel:
+ case_Oext:
Emit:
emiti(i);
i1 = curi; /* fixarg() can change curi */
@@ -461,7 +444,9 @@ Emit:
break;
default:
if (isext(i.op))
- goto case_OExt;
+ goto case_Oext;
+ if (isxsel(i.op))
+ goto case_Oxsel;
if (isload(i.op))
goto case_Oload;
if (iscmp(i.op, &kc, &x)) {
@@ -518,13 +503,13 @@ flagi(Ins *i0, Ins *i)
static Ins*
selsel(Fn *fn, Blk *b, Ins *i, Num *tn)
{
- Ref r, cr0, cr1;
+ Ref r, cr[2];
int c, k, swap, gencmp, gencpy;
Ins *isel0, *isel1, *fi;
Tmp *t;
assert(i->op == Osel1);
- for (isel0 = i; b->ins < isel0; isel0--) {
+ for (isel0=i; b->ins<isel0; isel0--) {
if (isel0->op == Osel0)
break;
assert(isel0->op == Osel1);
@@ -534,29 +519,38 @@ selsel(Fn *fn, Blk *b, Ins *i, Num *tn)
assert(rtype(r) == RTmp);
t = &fn->tmp[r.val];
fi = flagi(b->ins, isel0);
- cr0 = cr1 = R;
+ cr[0] = cr[1] = R;
gencmp = gencpy = swap = 0;
k = Kw;
c = Cine;
if (!fi || !req(fi->to, r)) {
gencmp = 1;
- cr0 = r;
- cr1 = CON_Z;
- } else if (iscmp(fi->op, &k, &c)
- && c != NCmpI+Cfeq /* see sel() */
- && c != NCmpI+Cfne) {
+ cr[0] = r;
+ cr[1] = CON_Z;
+ }
+ else if (iscmp(fi->op, &k, &c)) {
+ if (c == NCmpI+Cfeq
+ || c == NCmpI+Cfne) {
+ /* these are selected as 'and'
+ * or 'or', so we check their
+ * result with Cine
+ */
+ c = Cine;
+ goto Other;
+ }
swap = cmpswap(fi->arg, c);
if (swap)
c = cmpop(c);
if (t->nuse == 1) {
gencmp = 1;
- cr0 = fi->arg[0];
- cr1 = fi->arg[1];
+ cr[0] = fi->arg[0];
+ cr[1] = fi->arg[1];
*fi = (Ins){.op = Onop};
}
- } else if (fi->op == Oand && t->nuse == 1
- && (rtype(fi->arg[0]) == RTmp ||
- rtype(fi->arg[1]) == RTmp)) {
+ }
+ else if (fi->op == Oand && t->nuse == 1
+ && (rtype(fi->arg[0]) == RTmp ||
+ rtype(fi->arg[1]) == RTmp)) {
fi->op = Oxtest;
fi->to = R;
if (rtype(fi->arg[1]) == RCon) {
@@ -564,7 +558,9 @@ selsel(Fn *fn, Blk *b, Ins *i, Num *tn)
fi->arg[1] = fi->arg[0];
fi->arg[0] = r;
}
- } else {
+ }
+ else {
+ Other:
/* since flags are not tracked in liveness,
* the result of the flag-setting instruction
* has to be marked as live
@@ -573,18 +569,15 @@ selsel(Fn *fn, Blk *b, Ins *i, Num *tn)
gencpy = 1;
}
/* generate conditional moves */
- for (isel1 = i; isel0 < isel1; --isel1) {
- isel1->op = Oxselieq+c;
+ for (isel1=i; isel0<isel1; --isel1) {
+ isel1->op = Oxsel+c;
sel(*isel1, tn, fn);
}
- if (gencmp) {
- assert(!gencpy);
- selcmp((Ref[2]){cr0, cr1}, k, swap, fn);
- }
- if (gencpy) {
- assert(!gencmp);
+ assert(!gencmp || !gencpy);
+ if (gencmp)
+ selcmp(cr, k, swap, fn);
+ if (gencpy)
emit(Ocopy, Kw, R, r, R);
- }
*isel0 = (Ins){.op = Onop};
return isel0;
}
@@ -618,7 +611,7 @@ seljmp(Blk *b, Fn *fn)
b->jmp.type = Jjf + Cine;
}
else if (iscmp(fi->op, &k, &c)
- && c != NCmpI+Cfeq /* see sel() */
+ && c != NCmpI+Cfeq /* see sel(), selsel() */
&& c != NCmpI+Cfne) {
swap = cmpswap(fi->arg, c);
if (swap)