diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-02-11 16:10:08 -0500 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-02-11 16:12:11 -0500 |
commit | 53a5d7de2a7f84bf364753aaa3587121e8077937 (patch) | |
tree | 71ce6a5754f4dc91d97124e6a65431092f5519b9 /lisc | |
parent | 96251837db7c698a76d997f1449f0cd47885f203 (diff) | |
download | roux-53a5d7de2a7f84bf364753aaa3587121e8077937.tar.gz |
fp cmp fixes (highly untested)
Diffstat (limited to 'lisc')
-rw-r--r-- | lisc/emit.c | 48 | ||||
-rw-r--r-- | lisc/isel.c | 71 | ||||
-rw-r--r-- | lisc/lisc.h | 76 | ||||
-rw-r--r-- | lisc/parse.c | 20 |
4 files changed, 160 insertions, 55 deletions
diff --git a/lisc/emit.c b/lisc/emit.c index ecc6b36..3b916c4 100644 --- a/lisc/emit.c +++ b/lisc/emit.c @@ -74,12 +74,14 @@ static struct { { OXCmp, Kd, "comisd %D0, %D1" }, { OXCmp, Ki, "cmp%k %0, %1" }, { OXTest, Ki, "test%k %0, %1" }, - { OXSet+Ceq, Ki, "setz %B=\n\tmovzb%k %B=, %=" }, - { OXSet+Csle, Ki, "setle %B=\n\tmovzb%k %B=, %=" }, - { OXSet+Cslt, Ki, "setl %B=\n\tmovzb%k %B=, %=" }, - { OXSet+Csgt, Ki, "setg %B=\n\tmovzb%k %B=, %=" }, - { OXSet+Csge, Ki, "setge %B=\n\tmovzb%k %B=, %=" }, - { OXSet+Cne, Ki, "setnz %B=\n\tmovzb%k %B=, %=" }, + { OXSet+ICeq, Ki, "setz %B=\n\tmovzb%k %B=, %=" }, + { OXSet+ICsle, Ki, "setle %B=\n\tmovzb%k %B=, %=" }, + { OXSet+ICslt, Ki, "setl %B=\n\tmovzb%k %B=, %=" }, + { OXSet+ICsgt, Ki, "setg %B=\n\tmovzb%k %B=, %=" }, + { OXSet+ICsge, Ki, "setge %B=\n\tmovzb%k %B=, %=" }, + { OXSet+ICne, Ki, "setnz %B=\n\tmovzb%k %B=, %=" }, + { OXSet+ICXnp, Ki, "setnp %B=\n\tmovsb%k %B=, %=" }, + { OXSet+ICXp, Ki, "setp %B=\n\tmovsb%k %B=, %=" }, { NOp, 0, 0 } }; @@ -411,12 +413,18 @@ cneg(int cmp) { switch (cmp) { default: diag("emit: cneg() unhandled comparison"); - case Ceq: return Cne; - case Csle: return Csgt; - case Cslt: return Csge; - case Csgt: return Csle; - case Csge: return Cslt; - case Cne: return Ceq; + case ICule: return ICugt; + case ICult: return ICuge; + case ICsle: return ICsgt; + case ICslt: return ICsge; + case ICsgt: return ICsle; + case ICsge: return ICslt; + case ICugt: return ICule; + case ICuge: return ICult; + case ICeq: return ICne; + case ICne: return ICeq; + case ICXnp: return ICXp; + case ICXp: return ICXnp; } } @@ -437,8 +445,18 @@ void emitfn(Fn *fn, FILE *f) { static char *ctoa[] = { - [Ceq] = "z", [Csle] = "le", [Cslt] = "l", - [Csgt] = "g", [Csge] = "ge", [Cne] = "nz" + [ICeq] = "z", + [ICule] = "be", + [ICult] = "b", + [ICsle] = "le", + [ICslt] = "l", + [ICsgt] = "g", + [ICsge] = "ge", + [ICugt] = "a", + [ICuge] = "ae", + [ICne] = "nz", + [ICXnp] = "np", + [ICXp] = "p" }; Blk *b, *s; Ins *i, itmp; @@ -484,7 +502,7 @@ emitfn(Fn *fn, FILE *f) break; default: c = b->jmp.type - JXJc; - if (0 <= c && c <= NCmp) { + if (0 <= c && c <= NXICmp) { if (b->link == b->s2) { s = b->s1; } else if (b->link == b->s1) { diff --git a/lisc/isel.c b/lisc/isel.c index 45f793c..41ca011 100644 --- a/lisc/isel.c +++ b/lisc/isel.c @@ -31,6 +31,48 @@ struct ANum { static void amatch(Addr *, Ref, ANum *, Fn *, int); static int +fcmptoi(int fc) +{ + switch (fc) { + default: diag("isel: fcmptoi defaulted"); + case FCle: return ICule; + case FClt: return ICult; + case FCgt: return ICugt; + case FCge: return ICuge; + case FCne: return ICne; + case FCeq: return ICeq; + case FCo: return ICXnp; + case FCuo: return ICXp; + } +} + +static int +iscmp(int op, int *k, int *c) +{ + if (OCmpw <= op && op <= OCmpw1) { + *c = op - OCmpw; + *k = Kw; + return 1; + } + if (OCmpl <= op && op <= OCmpl1) { + *c = op - OCmpl; + *k = Kl; + return 1l; + } + if (OCmps <= op && op <= OCmps1) { + *c = fcmptoi(op - OCmps); + *k = Ks; + return 1; + } + if (OCmpd <= op && op <= OCmpd1) { + *c = fcmptoi(op - OCmpd); + *k = Kd; + return 1; + } + return 0; +} + +static int noimm(Ref r, Fn *fn) { int64_t val; @@ -159,7 +201,7 @@ static void sel(Ins i, ANum *an, Fn *fn) { Ref r0, r1; - int x, k; + int x, k, kc; int64_t val; Ins *i0; @@ -248,12 +290,11 @@ Emit: goto case_OExt; if (OLoad <= i.op && i.op <= OLoad1) goto case_OLoad; - if (OCmp <= i.op && i.op <= OCmp1) { - x = i.op - OCmp; + if (iscmp(i.op, &kc, &x)) { if (rtype(i.arg[0]) == RCon) - x = COP(x); - emit(OXSet+x, Kw, i.to, R, R); - selcmp(i.arg, k, fn); + x = icmpop(x); + emit(OXSet+x, k, i.to, R, R); + selcmp(i.arg, kc, fn); break; } diag("isel: non-exhaustive implementation"); @@ -271,7 +312,10 @@ flagi(Ins *i0, Ins *i) while (i>i0) switch ((--i)->op) { default: - if (OCmp <= i->op && i->op <= OCmp1) + if ((OCmpw <= i->op && i->op <= OCmpw1) + || (OCmpl <= i->op && i->op <= OCmpl1) + || (OCmps <= i->op && i->op <= OCmps1) + || (OCmpd <= i->op && i->op <= OCmpd1)) return i; if (OExt <= i->op && i->op <= OExt1) continue; @@ -295,7 +339,7 @@ static void seljmp(Blk *b, Fn *fn) { Ref r; - int c, w; + int c, w, k; Ins *fi; switch (b->jmp.type) { @@ -325,10 +369,9 @@ seljmp(Blk *b, Fn *fn) } fi = flagi(b->ins, &b->ins[b->nins]); if (fi && req(fi->to, r)) { - if (OCmp <= fi->op && fi->op <= OCmp1) { - c = fi->op - OCmp; + if (iscmp(fi->op, &k, &c)) { if (rtype(fi->arg[0]) == RCon) - c = COP(c); + c = icmpop(c); b->jmp.type = JXJc + c; if (fn->tmp[r.val].nuse == 1) { assert(fn->tmp[r.val].ndef == 1); @@ -342,7 +385,7 @@ seljmp(Blk *b, Fn *fn) rtype(fi->arg[1]) == RTmp)) { fi->op = OXTest; fi->to = R; - b->jmp.type = JXJc + Cne; + b->jmp.type = JXJc + ICne; if (rtype(fi->arg[1]) == RCon) { r = fi->arg[1]; fi->arg[1] = fi->arg[0]; @@ -351,12 +394,12 @@ seljmp(Blk *b, Fn *fn) return; } if (fn->tmp[r.val].nuse > 1) { - b->jmp.type = JXJc + Cne; + b->jmp.type = JXJc + ICne; return; } } selcmp((Ref[2]){r, CON_Z}, 0, fn); /* todo, add long branch if non-zero */ - b->jmp.type = JXJc + Cne; + b->jmp.type = JXJc + ICne; } struct AClass { diff --git a/lisc/lisc.h b/lisc/lisc.h index 2e99374..90f3ee2 100644 --- a/lisc/lisc.h +++ b/lisc/lisc.h @@ -150,22 +150,49 @@ static inline int isreg(Ref r) return rtype(r) == RTmp && r.val < Tmp0; } -#define CMPS(X) \ - X(eq) \ - X(sle) \ - X(slt) \ - X(sgt) \ - X(sge) \ - X(ne) /* mirror opposite cmps! */ - -#define COP(c) (c==Ceq||c==Cne ? c : NCmp-1 - c) - -enum Cmp { -#define X(c) C##c, - CMPS(X) +enum ICmp { +#define ICMPS(X) \ + X(ule) \ + X(ult) \ + X(sle) \ + X(slt) \ + X(sgt) \ + X(sge) \ + X(ugt) \ + X(uge) \ + X(eq) \ + X(ne) /* make sure icmpop() below works! */ + +#define X(c) IC##c, + ICMPS(X) #undef X + NICmp, - NCmp + ICXnp = NICmp, /* x64 specific */ + ICXp, + NXICmp +}; + +static inline int icmpop(int c) +{ + return c >= ICeq ? c : ICuge - c; +} + +enum FCmp { +#define FCMPS(X) \ + X(le) \ + X(lt) \ + X(gt) \ + X(ge) \ + X(ne) \ + X(eq) \ + X(o) \ + X(uo) + +#define X(c) FC##c, + FCMPS(X) +#undef X + NFCmp }; enum Class { @@ -188,8 +215,14 @@ enum Op { ORem, OMul, OAnd, - OCmp, - OCmp1 = OCmp + NCmp-1, + OCmpw, + OCmpw1 = OCmpw + NICmp-1, + OCmpl, + OCmpl1 = OCmpl + NICmp-1, + OCmps, + OCmps1 = OCmps + NFCmp-1, + OCmpd, + OCmpd1 = OCmpd + NFCmp-1, OStored, OStores, @@ -243,7 +276,8 @@ enum Op { OXDiv, OXCmp, OXSet, - OXSet1 = OXSet + NCmp-1, + OXSetnp = OXSet + NICmp, + OXSetp, OXTest, NOp }; @@ -257,7 +291,8 @@ enum Jmp { JJmp, JJnz, JXJc, - JXJc1 = JXJc + NCmp-1, + JXJnp = JXJc + NICmp, + JXJp, NJmp }; @@ -456,10 +491,9 @@ void copy(Fn *); Bits liveon(Blk *, Blk *); void filllive(Fn *); - /* isel.c */ -extern int rsave[NRSave]; -extern int rclob[NRClob]; +extern int rsave[/* NRSave */]; +extern int rclob[/* NRClob */]; ulong calldef(Ins, int[2]); ulong calluse(Ins, int[2]); void isel(Fn *); diff --git a/lisc/parse.c b/lisc/parse.c index b0d011c..a77904c 100644 --- a/lisc/parse.c +++ b/lisc/parse.c @@ -49,10 +49,18 @@ OpDesc opdesc[NOp] = { [OAlloc] = { "alloc4", 1 }, [OAlloc+1] = { "alloc8", 1 }, [OAlloc+2] = { "alloc16", 1 }, + [OXSetnp] = { "xsetnp", 0}, + [OXSetp] = { "xsetp", 0}, #define X(c) \ - [OCmp+C##c] = { "c" #c, 0 }, \ - [OXSet+C##c] = { "xset" #c, 0 }, - CMPS(X) + [OCmpw+IC##c] = { "c" #c "w", 0 }, \ + [OCmpl+IC##c] = { "c" #c "l", 0 }, \ + [OXSet+IC##c] = { "xset" #c, 0 }, + ICMPS(X) +#undef X +#define X(c) \ + [OCmps+FC##c] = { "c" #c "s", 0 }, \ + [OCmpd+FC##c] = { "c" #c "d", 0 }, + FCMPS(X) #undef X }; @@ -917,8 +925,10 @@ printfn(Fn *fn, FILE *f) [JRetl] = "retl", [JRetc] = "retc", [JJnz] = "jnz", - #define X(c) [JXJc+C##c] = "xj" #c, - CMPS(X) + [JXJnp] = "xjnp", + [JXJp] = "xjp", + #define X(c) [JXJc+IC##c] = "xj" #c, + ICMPS(X) #undef X }; static char prcls[NOp] = { |