summary refs log tree commit diff
path: root/lisc/tools
diff options
context:
space:
mode:
Diffstat (limited to 'lisc/tools')
-rw-r--r--lisc/tools/pmov.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/lisc/tools/pmov.c b/lisc/tools/pmov.c
new file mode 100644
index 0000000..246f4f0
--- /dev/null
+++ b/lisc/tools/pmov.c
@@ -0,0 +1,145 @@
+/*% cc -std=c99 -Wall -DTEST_PMOV -g -o # %
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../rega.c"
+
+int
+main()
+{
+	Blk dummyb;
+	Ins ins[NReg], *ip, *i1;
+	unsigned long long tm, rm;
+	RMap mbeg, mend;
+	int reg[NReg];
+	int t, i, r, nr;
+
+	tmp = (Tmp[Tmp0+NReg]){{0}};
+	for (t=0; t<Tmp0+NReg; t++)
+		if (t < Tmp0)
+			tmp[t] = (Tmp){.type = TReg};
+		else {
+			tmp[t].type = TLong;
+			tmp[t].hint = -1;
+			sprintf(tmp[t].name, "tmp%d", t-Tmp0+1);
+		}
+
+	dummyb.ins = ins;
+	strcpy(dummyb.name, "dummy");
+
+	for (tm = 0; tm < 1ull << (2*NReg); tm++) {
+		mbeg.n = 0;
+		mbeg.b = (Bits){{0}};
+		ip = ins;
+
+		/* find what temporaries are in copy and
+		 * wether or not they are in register
+		 */
+		for (t=0; t<NReg; t++)
+			switch ((tm >> (2*t)) & 3) {
+			case 0:
+				/* not in copy, not in use */
+				break;
+			case 1:
+				/* not in copy, in use */
+				radd(&mbeg, Tmp0+t, t+1);
+				break;
+			case 2:
+				/* in copy, not in reg */
+				*ip++ = (Ins){OCopy, TMP(Tmp0+t), {R, R}};
+				break;
+			case 3:
+				/* in copy, in reg */
+				*ip++ = (Ins){OCopy, TMP(Tmp0+t), {R, R}};
+				radd(&mbeg, Tmp0+t, t+1);
+				break;
+			}
+
+		if (ip == ins)
+			/* cancel is the parallel move
+			 * is empty
+			 */
+			goto Nxt;
+
+		/* find registers for temporaries
+		 * in mbeg
+		 */
+		nr = ip - ins;
+		dummyb.nins = nr;
+		rm = (1ull << (nr+1)) - 1;
+		for (i=0; i<nr; i++)
+			reg[i] = i+1;
+
+		for (;;) {
+			/* set registers on copies
+			 */
+			for (i=0, i1=ins; i1<ip; i1++, i++)
+				i1->arg[0] = TMP(reg[i]);
+#if 0
+			for (i=0; i<nr; i++)
+				printf("%d ", reg[i]);
+			printf("\n");
+#endif
+
+			/* compile the parallel move
+			 */
+			mend = mbeg;
+			dopm(&dummyb, ip-1, &mend);
+
+			// TODO
+			/* check that mend contain mappings for
+			 * source registers and does not map any
+			 * assigned temporary
+			 */
+
+			// TODO
+			/* execute the code generated and check
+			 * that all assigned temporaries got their
+			 * value
+			 */
+
+			/* find the next register assignment */
+			i = nr - 1;
+			for (;;) {
+				r = reg[i];
+				rm &= ~(1ull<<r);
+				do
+					r++;
+				while (r <= NReg && (rm & (1ull<<r)));
+				if (r == NReg+1) {
+					if (i == 0)
+						goto Nxt;
+					i--;
+				} else {
+					rm |= (1ull<<r);
+					reg[i++] = r;
+					break;
+				}
+			}
+			for (; i<nr; i++)
+				for (r=1; r<=NReg; r++)
+					if (!(rm & (1ull<<r))) {
+						rm |= (1ull<<r);
+						reg[i] = r;
+						break;
+					}
+		}
+	Nxt:	;
+	}
+	exit(0);
+}
+
+/* symbols required by the linker */
+char debug['Z'+1];
+Ins insb[NIns], *curi;
+
+void diag(char *s)
+{ printf("!diag failure: %s\n", s); exit(1); }
+
+void *alloc(size_t n)
+{ return malloc(n); }
+
+Blk *blocka()
+{ printf("!blocka called\n"); exit(1); }