commit 2c6f6b4b2dbdd94a10a01124ac61724c412fe587
parent 3c3175ca73914e299589b2e38692cd01b349d3d5
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Wed, 19 Aug 2015 14:56:33 -0400
add truncation operation
It would be nicer to have some kind of subtyping where a
l variable can be used in place of a w variable but it is
more complications than a truncation insutruction.
In some cases, it might be less efficient than the above
solution by requiring two registers instead of one.
(I.e when both the truncated variable and the long variable
live together.)
We have to see what are the usage patterns.
Diffstat:
4 files changed, 13 insertions(+), 0 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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 },