diff options
-rw-r--r-- | lisc/emit.c | 7 | ||||
-rw-r--r-- | lisc/isel.c | 4 | ||||
-rw-r--r-- | lisc/lisc.h | 1 | ||||
-rw-r--r-- | lisc/parse.c | 1 |
4 files changed, 13 insertions, 0 deletions
diff --git a/lisc/emit.c b/lisc/emit.c index 1f2060b..e28832a 100644 --- a/lisc/emit.c +++ b/lisc/emit.c @@ -191,6 +191,13 @@ eins(Ins i, Fn *fn, FILE *f) diag("emit: invalid extension"); eop(otoa[i.op], i.arg[0], i.to, fn, f); break; + case OTrunc: + if (rtype(i.to) != RTmp || i.to.val < EAX + || (rtype(i.arg[0]) == RTmp && i.arg[0].val >= EAX)) + diag("emit: invalid truncation"); + if (rtype(i.arg[0]) == RTmp) + i.arg[0] = TMP(RWORD(i.arg[0].val)); + /* fall through */ case OCopy: if (req(i.to, R)) break; diff --git a/lisc/isel.c b/lisc/isel.c index bace637..91df7dc 100644 --- a/lisc/isel.c +++ b/lisc/isel.c @@ -181,6 +181,9 @@ sel(Ins i, Fn *fn) case OZext: n = 0; goto Emit; + case OTrunc: + n = 1; + goto Emit; case OAdd: case OSub: case OMul: @@ -285,6 +288,7 @@ flagi(Ins *i0, Ins *i) case OCopy: /* flag-transparent */ case OSext: case OZext: + case OTrunc: case OStorel: case OStorew: case OStoreb: diff --git a/lisc/lisc.h b/lisc/lisc.h index d924701..b2f1c66 100644 --- a/lisc/lisc.h +++ b/lisc/lisc.h @@ -130,6 +130,7 @@ enum Op { OAnd, OSext, OZext, + OTrunc, OCmp, OCmp1 = OCmp + NCmp-1, OStorel, diff --git a/lisc/parse.c b/lisc/parse.c index 8ffdb74..9f8e7a6 100644 --- a/lisc/parse.c +++ b/lisc/parse.c @@ -20,6 +20,7 @@ OpDesc opdesc[NOp] = { [OAnd] = { "and", 2, 2 }, [OSext] = { "sext", 1, 1 }, [OZext] = { "zext", 1, 1 }, + [OTrunc] = { "trunc", 1, 1 }, [OStorel] = { "storel", 2, 0 }, [OStorew] = { "storew", 2, 0 }, [OStores] = { "stores", 2, 0 }, |