summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lisc/emit.c7
-rw-r--r--lisc/isel.c4
-rw-r--r--lisc/lisc.h1
-rw-r--r--lisc/parse.c1
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 },