summary refs log tree commit diff
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 },