diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-08-16 11:34:52 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-09-15 23:01:31 -0400 |
commit | 16fe5c13668d9ccc8f3b14c6c20565dfe5a26d57 (patch) | |
tree | 70a7bce825b8d57b74d776c8e2292369a12e97c5 | |
parent | ca3dc70ff3e4caf57f32e5a0da7be29ccf222213 (diff) | |
download | roux-16fe5c13668d9ccc8f3b14c6c20565dfe5a26d57.tar.gz |
compile branches on and using test
-rw-r--r-- | lisc/emit.c | 9 | ||||
-rw-r--r-- | lisc/isel.c | 27 | ||||
-rw-r--r-- | lisc/lisc.h | 7 | ||||
-rw-r--r-- | lisc/parse.c | 2 |
4 files changed, 35 insertions, 10 deletions
diff --git a/lisc/emit.c b/lisc/emit.c index 00bce4b..3e03a81 100644 --- 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 index 97a0124..41ff9f2 100644 --- 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 index 50c6504..76290dc 100644 --- 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 index f51d5a5..4856d5c 100644 --- 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 }, |