commit 16fe5c13668d9ccc8f3b14c6c20565dfe5a26d57
parent ca3dc70ff3e4caf57f32e5a0da7be29ccf222213
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Sun, 16 Aug 2015 11:34:52 -0400
compile branches on and using test
Diffstat:
4 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/lisc/emit.c b/lisc/emit.c
@@ -145,6 +145,10 @@ eins(Ins i, Fn *fn, FILE *f)
[OLoadus] = "movzw",
[OLoadsb] = "movsb",
[OLoadub] = "movzb",
+ [OXCmpw] = "cmpl",
+ [OXCmpl] = "cmpq",
+ [OXTestw] = "testl",
+ [OXTestl] = "testq",
};
static char *stoa[] = {
[OStorel - OStorel] = "q",
@@ -240,8 +244,9 @@ eins(Ins i, Fn *fn, FILE *f)
break;
case OXCmpw:
case OXCmpl:
- eop(i.op == OXCmpw ? "cmpl" : "cmpq",
- i.arg[0], i.arg[1], fn, f);
+ case OXTestw:
+ case OXTestl:
+ eop(otoa[i.op], i.arg[0], i.arg[1], fn, f);
break;
case ONop:
break;
diff --git a/lisc/isel.c b/lisc/isel.c
@@ -173,6 +173,10 @@ sel(Ins i, Fn *fn)
break;
case ONop:
break;
+ case OXTestw:
+ case OXTestl:
+ n = 2;
+ goto Emit;
case OAdd:
case OSub:
case OAnd:
@@ -318,15 +322,26 @@ seljmp(Blk *b, Fn *fn)
selcmp(fi->arg, fn);
*fi = (Ins){ONop, R, {R, R}};
}
- } else {
- if (fn->tmp[r.val].nuse == 1)
- emit(OCopy, R, r, R);
+ return;
+ }
+ if (fi->op == OAnd && fn->tmp[r.val].nuse == 1
+ && (rtype(fi->arg[0]) == RTmp ||
+ rtype(fi->arg[1]) == RTmp)) {
+ if (fn->tmp[r.val].type == TLong)
+ fi->op = OXTestl;
+ else
+ fi->op = OXTestw;
+ fi->to = R;
b->jmp.type = JXJc + Cne;
+ return;
+ }
+ if (fn->tmp[r.val].nuse > 1) {
+ b->jmp.type = JXJc + Cne;
+ return;
}
- } else {
- selcmp((Ref[2]){r, CON_Z}, fn);
- b->jmp.type = JXJc + Cne;
}
+ selcmp((Ref[2]){r, CON_Z}, fn);
+ b->jmp.type = JXJc + Cne;
}
int
diff --git a/lisc/lisc.h b/lisc/lisc.h
@@ -58,7 +58,7 @@ enum Reg {
Tmp0, /* first non-reg temporary */
- NReg = RDX - RAX + 1
+ NReg = R11 - RAX + 1
};
#define RWORD(r) (r + (EAX-RAX))
@@ -139,13 +139,14 @@ enum Op {
OLoadus,
OLoadsb,
OLoadub,
- OCopy,
OAlloc,
OAlloc1 = OAlloc + 2,
+ OCopy,
NPubOp,
/* reserved instructions */
ONop = NPubOp,
+ OAddr,
OSwap,
OSign,
OXDiv,
@@ -153,6 +154,8 @@ enum Op {
OXCmpl,
OXSet,
OXSet1 = OXSet + NCmp-1,
+ OXTestw,
+ OXTestl,
NOp
};
diff --git a/lisc/parse.c b/lisc/parse.c
@@ -33,6 +33,8 @@ OpDesc opdesc[NOp] = {
[OXDiv] = { "xdiv", 1, 1 },
[OXCmpw] = { "xcmpw", 2, 1 },
[OXCmpl] = { "xcmpl", 2, 1 },
+ [OXTestw] = { "xtestw", 2, 1 },
+ [OXTestl] = { "xtestl", 2, 1 },
[OAlloc] = { "alloc4", 1, 1 },
[OAlloc+1] = { "alloc8", 1, 1 },
[OAlloc+2] = { "alloc16", 1, 1 },