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 <stdlib.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"
|
||||
|
||||
static RMap mbeg;
|
||||
static Ins ins[NReg], *ip;
|
||||
static Blk dummyb = { .ins = ins };
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
Blk dummyb;
|
||||
Ins *i1;
|
||||
unsigned long long tm, rm;
|
||||
unsigned long long tm, rm, cnt;
|
||||
RMap mend;
|
||||
int reg[NReg];
|
||||
int reg[NReg], val[NReg+1];
|
||||
int t, i, r, nr;
|
||||
|
||||
tmp = (Tmp[Tmp0+NReg]){{0}};
|
||||
|
@ -31,9 +38,7 @@ main()
|
|||
sprintf(tmp[t].name, "tmp%d", t-Tmp0+1);
|
||||
}
|
||||
|
||||
dummyb.ins = ins;
|
||||
strcpy(dummyb.name, "dummy");
|
||||
|
||||
cnt = 0;
|
||||
for (tm = 0; tm < 1ull << (2*NReg); tm++) {
|
||||
mbeg.n = 0;
|
||||
mbeg.b = (Bits){{0}};
|
||||
|
@ -63,7 +68,7 @@ main()
|
|||
}
|
||||
|
||||
if (ip == ins)
|
||||
/* cancel is the parallel move
|
||||
/* cancel if the parallel move
|
||||
* is empty
|
||||
*/
|
||||
goto Nxt;
|
||||
|
@ -72,7 +77,6 @@ main()
|
|||
* in mbeg
|
||||
*/
|
||||
nr = ip - ins;
|
||||
dummyb.nins = nr;
|
||||
rm = (1ull << (nr+1)) - 1;
|
||||
for (i=0; i<nr; i++)
|
||||
reg[i] = i+1;
|
||||
|
@ -82,28 +86,51 @@ main()
|
|||
*/
|
||||
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);
|
||||
cnt++;
|
||||
|
||||
// TODO
|
||||
/* check that mend contain mappings for
|
||||
* 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
|
||||
* 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 */
|
||||
i = nr - 1;
|
||||
|
@ -133,11 +160,59 @@ main()
|
|||
}
|
||||
Nxt: ;
|
||||
}
|
||||
printf("%llu tests successful!\n", cnt);
|
||||
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 */
|
||||
|
||||
static int re;
|
||||
|
||||
static void
|
||||
replay()
|
||||
{
|
||||
RMap mend;
|
||||
|
||||
re = 1;
|
||||
mend = mbeg;
|
||||
dopm(&dummyb, ip-1, &mend);
|
||||
}
|
||||
|
||||
static void
|
||||
fail()
|
||||
{
|
||||
|
@ -155,6 +230,7 @@ fail()
|
|||
printf("\t %s <- r%d\n",
|
||||
tmp[i1->to.val].name,
|
||||
i1->arg[0].val);
|
||||
replay();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -163,20 +239,26 @@ assert_test(char *s, int x)
|
|||
{
|
||||
if (x)
|
||||
return;
|
||||
if (re)
|
||||
exit(1);
|
||||
printf("!assertion failure: %s\n", s);
|
||||
fail();
|
||||
}
|
||||
|
||||
void diag(char *s)
|
||||
{
|
||||
if (re)
|
||||
exit(1);
|
||||
printf("!diag failure: %s\n", s);
|
||||
fail();
|
||||
}
|
||||
|
||||
|
||||
/* symbols required by the linker */
|
||||
char debug['Z'+1];
|
||||
Ins insb[NIns], *curi;
|
||||
|
||||
void diag(char *s)
|
||||
{ printf("!diag failure: %s\n", s); fail(); }
|
||||
|
||||
void *alloc(size_t n)
|
||||
{ return malloc(n); }
|
||||
|
||||
{ return calloc(n, 1); }
|
||||
Blk *blocka()
|
||||
{ printf("!blocka called\n"); exit(1); }
|
||||
{ printf("!blocka\n"); exit(1); }
|
||||
|
|
Loading…
Add table
Reference in a new issue