Add a negation instruction

Necessary for floating-point negation, because
`%result = sub 0, %operand` doesn't give the correct sign for 0/-0.
This commit is contained in:
Eyal Sawady 2022-01-17 22:00:48 +00:00 committed by Quentin Carbonneaux
parent 367c8215d9
commit e91d121581
8 changed files with 28 additions and 13 deletions

View file

@ -365,6 +365,7 @@ emitins(Ins i, Fn *fn, FILE *f)
Ref r;
int64_t val;
int o, t0;
Ins ineg;
switch (i.op) {
default:
@ -376,7 +377,7 @@ emitins(Ins i, Fn *fn, FILE *f)
/* this linear search should really be a binary
* search */
if (omap[o].op == NOp)
die("no match for %s(%d)",
die("no match for %s(%c)",
optab[i.op].name, "wlsd"[i.cls]);
if (omap[o].op == i.op)
if (omap[o].cls == i.cls
@ -409,20 +410,26 @@ emitins(Ins i, Fn *fn, FILE *f)
/* we have to use the negation trick to handle
* some 3-address subtractions */
if (req(i.to, i.arg[1]) && !req(i.arg[0], i.to)) {
if (KBASE(i.cls) == 0)
emitf("neg%k %=", &i, fn, f);
else
fprintf(f,
"\txorp%c %sfp%d(%%rip), %%%s\n",
"xxsd"[i.cls],
gasloc,
gasstash(negmask[i.cls], 16),
regtoa(i.to.val, SLong)
);
ineg = (Ins){Oneg, i.cls, i.to, {i.to}};
emitins(ineg, fn, f);
emitf("add%k %0, %=", &i, fn, f);
break;
}
goto Table;
case Oneg:
if (!req(i.to, i.arg[0]))
emitf("mov%k %0, %=", &i, fn, f);
if (KBASE(i.cls) == 0)
emitf("neg%k %=", &i, fn, f);
else
fprintf(f,
"\txorp%c %sfp%d(%%rip), %%%s\n",
"xxsd"[i.cls],
gasloc,
gasstash(negmask[i.cls], 16),
regtoa(i.to.val, SLong)
);
break;
case Odiv:
/* use xmm15 to adjust the instruction when the
* conversion to 2-address in emitf() would fail */

View file

@ -290,6 +290,7 @@ sel(Ins i, ANum *an, Fn *fn)
case Ocopy:
case Oadd:
case Osub:
case Oneg:
case Omul:
case Oand:
case Oor: