write more tests for dopm()
This commit is contained in:
parent
13e04cd1de
commit
60b8b06aab
1 changed files with 107 additions and 25 deletions
|
@ -1,24 +1,31 @@
|
||||||
/*% cc -std=c99 -Wall -DTEST_PMOV -g -o # %
|
/*% cc -O3 -std=c99 -Wall -DTEST_PMOV -o # %
|
||||||
|
*
|
||||||
|
* This is a test framwork for the dopm() function
|
||||||
|
* in rega.c, use it when you want to modify it or
|
||||||
|
* all the parallel move functions.
|
||||||
|
*
|
||||||
|
* You might need to decrease NReg to see it
|
||||||
|
* terminate, I used NReg == 7 at most.
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static void assert_test(char *, int), fail(void);
|
static void assert_test(char *, int), fail(void), iexec(int *);
|
||||||
|
|
||||||
#include "../rega.c"
|
#include "../rega.c"
|
||||||
|
|
||||||
static RMap mbeg;
|
static RMap mbeg;
|
||||||
static Ins ins[NReg], *ip;
|
static Ins ins[NReg], *ip;
|
||||||
|
static Blk dummyb = { .ins = ins };
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
Blk dummyb;
|
|
||||||
Ins *i1;
|
Ins *i1;
|
||||||
unsigned long long tm, rm;
|
unsigned long long tm, rm, cnt;
|
||||||
RMap mend;
|
RMap mend;
|
||||||
int reg[NReg];
|
int reg[NReg], val[NReg+1];
|
||||||
int t, i, r, nr;
|
int t, i, r, nr;
|
||||||
|
|
||||||
tmp = (Tmp[Tmp0+NReg]){{0}};
|
tmp = (Tmp[Tmp0+NReg]){{0}};
|
||||||
|
@ -31,9 +38,7 @@ main()
|
||||||
sprintf(tmp[t].name, "tmp%d", t-Tmp0+1);
|
sprintf(tmp[t].name, "tmp%d", t-Tmp0+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
dummyb.ins = ins;
|
cnt = 0;
|
||||||
strcpy(dummyb.name, "dummy");
|
|
||||||
|
|
||||||
for (tm = 0; tm < 1ull << (2*NReg); tm++) {
|
for (tm = 0; tm < 1ull << (2*NReg); tm++) {
|
||||||
mbeg.n = 0;
|
mbeg.n = 0;
|
||||||
mbeg.b = (Bits){{0}};
|
mbeg.b = (Bits){{0}};
|
||||||
|
@ -63,7 +68,7 @@ main()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip == ins)
|
if (ip == ins)
|
||||||
/* cancel is the parallel move
|
/* cancel if the parallel move
|
||||||
* is empty
|
* is empty
|
||||||
*/
|
*/
|
||||||
goto Nxt;
|
goto Nxt;
|
||||||
|
@ -72,7 +77,6 @@ main()
|
||||||
* in mbeg
|
* in mbeg
|
||||||
*/
|
*/
|
||||||
nr = ip - ins;
|
nr = ip - ins;
|
||||||
dummyb.nins = nr;
|
|
||||||
rm = (1ull << (nr+1)) - 1;
|
rm = (1ull << (nr+1)) - 1;
|
||||||
for (i=0; i<nr; i++)
|
for (i=0; i<nr; i++)
|
||||||
reg[i] = i+1;
|
reg[i] = i+1;
|
||||||
|
@ -82,28 +86,51 @@ main()
|
||||||
*/
|
*/
|
||||||
for (i=0, i1=ins; i1<ip; i1++, i++)
|
for (i=0, i1=ins; i1<ip; i1++, i++)
|
||||||
i1->arg[0] = TMP(reg[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
|
/* compile the parallel move
|
||||||
*/
|
*/
|
||||||
mend = mbeg;
|
mend = mbeg;
|
||||||
dopm(&dummyb, ip-1, &mend);
|
dopm(&dummyb, ip-1, &mend);
|
||||||
|
cnt++;
|
||||||
|
|
||||||
// TODO
|
|
||||||
/* check that mend contain mappings for
|
/* check that mend contain mappings for
|
||||||
* source registers and does not map any
|
* source registers and does not map any
|
||||||
* assigned temporary
|
* assigned temporary, then check that
|
||||||
|
* all temporaries in mend are mapped in
|
||||||
|
* mbeg and not used in the copy
|
||||||
*/
|
*/
|
||||||
|
for (i1=ins; i1<ip; i1++) {
|
||||||
|
r = i1->arg[0].val;
|
||||||
|
assert(rfree(&mend, r) == r);
|
||||||
|
t = i1->to.val;
|
||||||
|
assert(!BGET(mend.b, t));
|
||||||
|
}
|
||||||
|
for (i=0; i<mend.n; i++) {
|
||||||
|
t = mend.t[i];
|
||||||
|
assert(BGET(mbeg.b, t));
|
||||||
|
t -= Tmp0;
|
||||||
|
assert(((tm >> (2*t)) & 3) == 1);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
/* execute the code generated and check
|
/* execute the code generated and check
|
||||||
* that all assigned temporaries got their
|
* that all assigned temporaries got their
|
||||||
* value
|
* value, and that all live variables's
|
||||||
|
* content got preserved
|
||||||
*/
|
*/
|
||||||
|
for (i=1; i<=NReg; i++)
|
||||||
|
val[i] = i;
|
||||||
|
iexec(val);
|
||||||
|
for (i1=ins; i1<ip; i1++) {
|
||||||
|
t = i1->to.val;
|
||||||
|
r = rfind(&mbeg, t);
|
||||||
|
if (r != -1)
|
||||||
|
assert(val[r] == i1->arg[0].val);
|
||||||
|
}
|
||||||
|
for (i=0; i<mend.n; i++) {
|
||||||
|
t = mend.t[i];
|
||||||
|
r = mend.r[i];
|
||||||
|
assert(val[t-Tmp0+1] == r);
|
||||||
|
}
|
||||||
|
|
||||||
/* find the next register assignment */
|
/* find the next register assignment */
|
||||||
i = nr - 1;
|
i = nr - 1;
|
||||||
|
@ -133,11 +160,59 @@ main()
|
||||||
}
|
}
|
||||||
Nxt: ;
|
Nxt: ;
|
||||||
}
|
}
|
||||||
|
printf("%llu tests successful!\n", cnt);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* execute what pmgen() wrote (swap, copy) */
|
||||||
|
|
||||||
|
#define validr(r) \
|
||||||
|
rtype(r) == RTmp && \
|
||||||
|
r.val > 0 && \
|
||||||
|
r.val <= NReg
|
||||||
|
|
||||||
|
static void
|
||||||
|
iexec(int val[])
|
||||||
|
{
|
||||||
|
Ins *i;
|
||||||
|
int t;
|
||||||
|
|
||||||
|
for (i=insb; i<curi; i++)
|
||||||
|
switch (i->op) {
|
||||||
|
default:
|
||||||
|
assert(!"iexec: missing case\n");
|
||||||
|
exit(1);
|
||||||
|
case OSwap:
|
||||||
|
assert(validr(i->arg[0]));
|
||||||
|
assert(validr(i->arg[1]));
|
||||||
|
t = val[i->arg[0].val];
|
||||||
|
val[i->arg[0].val] = val[i->arg[1].val];
|
||||||
|
val[i->arg[1].val] = t;
|
||||||
|
break;
|
||||||
|
case OCopy:
|
||||||
|
assert(validr(i->to));
|
||||||
|
assert(validr(i->arg[0]));
|
||||||
|
val[i->to.val] = val[i->arg[0].val];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* failure diagnostics */
|
/* failure diagnostics */
|
||||||
|
|
||||||
|
static int re;
|
||||||
|
|
||||||
|
static void
|
||||||
|
replay()
|
||||||
|
{
|
||||||
|
RMap mend;
|
||||||
|
|
||||||
|
re = 1;
|
||||||
|
mend = mbeg;
|
||||||
|
dopm(&dummyb, ip-1, &mend);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fail()
|
fail()
|
||||||
{
|
{
|
||||||
|
@ -155,6 +230,7 @@ fail()
|
||||||
printf("\t %s <- r%d\n",
|
printf("\t %s <- r%d\n",
|
||||||
tmp[i1->to.val].name,
|
tmp[i1->to.val].name,
|
||||||
i1->arg[0].val);
|
i1->arg[0].val);
|
||||||
|
replay();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,20 +239,26 @@ assert_test(char *s, int x)
|
||||||
{
|
{
|
||||||
if (x)
|
if (x)
|
||||||
return;
|
return;
|
||||||
|
if (re)
|
||||||
|
exit(1);
|
||||||
printf("!assertion failure: %s\n", s);
|
printf("!assertion failure: %s\n", s);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void diag(char *s)
|
||||||
|
{
|
||||||
|
if (re)
|
||||||
|
exit(1);
|
||||||
|
printf("!diag failure: %s\n", s);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* symbols required by the linker */
|
/* symbols required by the linker */
|
||||||
char debug['Z'+1];
|
char debug['Z'+1];
|
||||||
Ins insb[NIns], *curi;
|
Ins insb[NIns], *curi;
|
||||||
|
|
||||||
void diag(char *s)
|
|
||||||
{ printf("!diag failure: %s\n", s); fail(); }
|
|
||||||
|
|
||||||
void *alloc(size_t n)
|
void *alloc(size_t n)
|
||||||
{ return malloc(n); }
|
{ return calloc(n, 1); }
|
||||||
|
|
||||||
Blk *blocka()
|
Blk *blocka()
|
||||||
{ printf("!blocka called\n"); exit(1); }
|
{ printf("!blocka\n"); exit(1); }
|
||||||
|
|
Loading…
Add table
Reference in a new issue