Initial revision

This commit is contained in:
keie 1985-01-01 19:30:24 +00:00
parent 6a08d40d15
commit 5662050ad3
8 changed files with 4030 additions and 0 deletions

19
emtest/Makefile Normal file
View file

@ -0,0 +1,19 @@
tested: last
set -x ;\
for i in `awk '{for(i=\$$1;i<=127;i++)print i}' last ` ;\
do \
echo $$i; \
echo $$i >last; \
select $$i tests > test.e; \
ack test.e; \
a.out \
: ok; \
done
rm -f test.e a.out
>tested
last: tests test.h select
echo 0 >last
select: select.c
cc -O -n -o select select.c

132
emtest/READ_ME Normal file
View file

@ -0,0 +1,132 @@
This directory contains test programs for EM implementations.
The test programs are all part of the file "tests".
Each individual test program looks like:
TEST 004: test ...
... ; data declarations etc.
MAIN nlocal
... ; part of the body of MAIN
PROC
... ; subroutines used by this test
The PROC part is optional, so the smallest test program looks like:
TEST 000: null test
MAIN 0
The keywords used by "select", like TEST, MAIN, PROC, HOL, OK and ERRLAB,
all consist of upper case letters and start in column one.
A convention for test numbers is to use 3 digit numbers, possibly left
padded with zero's.
A program, called "select", is provided to combine a range of tests
into a single test program.
"Select" expects a range as argument, like 0-127, or -127, or 0-.
Tests that have a TEST number in that range are included.
To prevent name clashes, some rules must be obeyed:
- data label names, procedure names and instruction label numbers
must be unique over all tests. A good habit is to use the
three digit test number as suffix.
- only keyword of "select" may start with uppercase letters in column
one, to allow for expansion in the future.
- because only a single 'hol' pseudo is allowed, "select" must
generate the 'hol' pseudo. An individual test may request
some 'hol' space by a special HOL line, starting in column one
and followed by a single number, the number of bytes needed.
This number must consists of digits only, no constant symbols,
because "select" must compute the maximum, so before the
preprocessor has replaced the constant symbols by their values.
- a similar problem is caused by the number of bytes of local
storage for 'main'. An individual test may specify the number
of bytes it needs as parameter to the MAIN line.
Again, the number must consist of digits only.
Test programs print a sequence of integers greater than 1.
This sequence is terminated by the number 1 as soon as an error is detected.
If all tests are performed correctedly the number 0 is printed.
To allow test programs to print integers without the full machinery of
conversion and i/o routines, the EM instruction 'nop' is used.
Each time this instruction is executed, the current line number as
maintained by the 'lin' instruction must be printed, followed by a
newline, at least during debugging.
The following abbrevation may be used in test programs:
OK -> lin n
nop
Numbers are automatically assigned in order of static appearance.
As soon as an error is detected you must branch to label 1, by instructions
like 'bra *1' and 'zne *1'.
Label 1 is automatically provided in the main routine.
If you jump to label 1 in a subroutine, then that subroutine must
end with ERRLAB, like in:
PROC
pro $test,0
...
bra *1
...
ret 0
ERRLAB
end
An option to "select" is to generate 'fil' instructions whenever a
new test starts.
This is useful if 'nop' prints the 'fil' string as well as the 'lin' number.
This 'f' option is on by default, off if a '-f' flag is given.
The EM file generated by "select" includes "test.h".
"Emtest.h" may contain definitions of the following symbols:
W2S: the size of double precision integers, if implemented.
FS: the size of single precision floats, if implemented.
F2S: the size of double precision floats, if implemented.
The value of these symbols, if defined, must be the size of the object involved.
Two other symbols are used:
EM_PSIZE: pointer size
EM_WSIZE: word size
The machine dependent translation program, like 8086 and vax2, give
definitions of these symbols while calling the EM encode program.
Because these size names occur quite often, they may be abbreviated:
WS -> EM_WSIZE
PS -> EM_PSIZE
Before running the tests in the file "tests", it is wise to test
the necessary basic functions with some simple tests like
TEST 000: null
MAIN 0
and
TEST 001: ok
MAIN 0
OK
and
TEST 998: error
MAIN 0
bra *1
and
TEST 999: test lni
MAIN 0
lin 1
lni
loe 0
loc 2
bne *1
OK
The first two of these are part of "tests" as well. The last two are
not included in "tests" intensionally, because they would fail.
The last tests fails because it references the ABS block which is
inaccessable after an 'hol' pseudo.
Proceed as follows for each of these basic tests:
- make a file called 'basic' containing the test
- run select:
select basic >basic.e
- compile by
machine basic.e
- and load and run
where machine should be replaced by the name of program
used to compile EM programs for the current machine.

1
emtest/last Normal file
View file

@ -0,0 +1 @@
0

10
emtest/ok Executable file
View file

@ -0,0 +1,10 @@
trap "" 1 2
while read x
do
case $x in
0) exit 0;;
bad) exit 1;;
esac
done
exit 1

249
emtest/select.c Normal file
View file

@ -0,0 +1,249 @@
/*
* (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
*
* This product is part of the Amsterdam Compiler Kit.
*
* Permission to use, sell, duplicate or disclose this software must be
* obtained in writing. Requests for such permissions may be sent to
*
* Dr. Andrew S. Tanenbaum
* Wiskundig Seminarium
* Vrije Universiteit
* Postbox 7161
* 1007 MC Amsterdam
* The Netherlands
*
*/
#include <stdio.h>
#include <assert.h>
#include <signal.h>
#define LINSIZ 100
int sigs[] = {
SIGHUP,
SIGINT,
SIGQUIT,
SIGTERM,
0
};
char *prog;
char line[LINSIZ];
int nlocals = 0;
int nhol = 0;
int nerrors = 0;
int oknum = 2;
int fflag = 1;
int low = 0;
int high = 999;
FILE *file1;
FILE *file2;
FILE *file3;
char name1[] = "/usr/tmp/f1XXXXXX";
char name2[] = "/usr/tmp/f2XXXXXX";
char name3[] = "/usr/tmp/f3XXXXXX";
stop() {
unlink(name1);
unlink(name2);
unlink(name3);
exit(nerrors);
}
main(argc,argv) char **argv; {
register *p;
register char *s;
prog = *argv++; --argc;
mktemp(name1);
mktemp(name2);
mktemp(name3);
for (p = sigs; *p; p++)
if (signal(*p, stop) == SIG_IGN)
signal(*p, SIG_IGN);
while (argc > 0 && argv[0][0] == '-') {
switch (argv[0][1]) {
case 'f':
fflag ^= 1;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
high = atoi(&argv[0][1]);
break;
default:
usage();
break;
}
argc--;
argv++;
}
if (argc > 0 && argv[0][0] >= '0' && argv[0][0] <= '9') {
s = argv[0];
do
low = low*10 + *s++ - '0';
while (*s >= '0' && *s <= '9');
if (*s == 0)
high = low;
else if (*s++ == '-') {
high = atoi(s);
if (high == 0)
high = 999;
} else
fatal("bad range %s", argv[0]);
argc--;
argv++;
}
if (argc > 1)
usage();
if (argc == 1 && freopen(argv[0], "r", stdin) == NULL)
fatal("cannot open %s", argv[0]);
if ((file1 = fopen(name1, "w")) == NULL)
fatal("cannot create %s", name1);
if ((file2 = fopen(name2, "w")) == NULL)
fatal("cannot create %s", name2);
if ((file3 = fopen(name3, "w")) == NULL)
fatal("cannot create %s", name3);
if (getline())
while (select())
;
fclose(file1);
fclose(file2);
fclose(file3);
combine();
stop();
}
select() {
register FILE *f;
int i;
if (sscanf(line, "TEST %d", &i) != 1)
fatal("bad test identification(%s)", line);
if (i < low || i > high) {
while (getline())
if (line[0] == 'T')
return(1);
return(0);
}
fprintf(file2, "; %s\n", line);
if (fflag) {
fprintf(file1, ".%03d\n", i);
fprintf(file1, " con \"tst%03d\"\n", i);
fprintf(file2, " fil .%03d\n", i);
}
f = file1;
while (getline()) {
switch (line[0]) {
case 'T':
return(1);
case 'M':
if (sscanf(line, "MAIN%d", &i) != 1 || i%4 != 0)
break;
if (i > nlocals)
nlocals = i;
f = file2;
continue;
case 'P':
if (strcmp(line, "PROC") != 0)
break;
f = file3;
continue;
case 'H':
if (f != file1 ||
sscanf(line, "HOL%d", &i) != 1 ||
i%4 != 0)
break;
if (i > nhol)
nhol = i;
continue;
case 'O':
if (strcmp(line, "OK") != 0)
break;
fprintf(f, " lin %d\n nop\n", oknum++);
continue;
case 'E':
if (f != file3 || strcmp(line, "ERRLAB") != 0)
break;
fprintf(f, "1\n lin 1\n nop\n loc 1\n loc 1\n mon\n");
continue;
default:
putline(f);
continue;
}
fatal("bad line (%s)", line);
}
return(0);
}
combine() {
printf("#define WS EM_WSIZE\n");
printf("#define PS EM_PSIZE\n");
printf("#include \"test.h\"\n");
printf(" mes 2,WS,PS\n");
printf(" mes 1\n");
printf(" mes 4,300\n");
if (nhol)
printf(" hol %d,0,0\n", nhol);
copy(name1);
printf(" exp $m_a_i_n\n");
printf(" pro $m_a_i_n,%d\n", nlocals);
printf(" loc 123\n");
printf(" loc -98\n");
copy(name2);
printf(" loc -98\n");
printf(" bne *1\n");
printf(" loc 123\n");
printf(" bne *1\n");
printf(" lin 0\n");
printf(" nop\n");
printf(" loc 0\n");
printf(" ret WS\n");
printf("1\n");
printf(" lin 1\n");
printf(" nop\n");
printf(" loc 1\n");
printf(" ret WS\n");
printf(" end\n");
copy(name3);
}
copy(s) char *s; {
if (freopen(s, "r", stdin) == NULL)
fatal("cannot reopen %s", s);
while (getline())
putline(stdout);
}
getline() {
register len;
if (fgets(line, LINSIZ, stdin) == NULL)
return(0);
len = strlen(line);
if (line[len-1] != '\n')
fatal("line too long(%s)", line);
line[len-1] = 0;
return(1);
}
putline(f) FILE *f; {
fprintf(f, "%s\n", line);
}
fatal(s, a1, a2, a3, a4) char *s; {
fprintf(stderr, "%s: ", prog);
fprintf(stderr, s, a1, a2, a3, a4);
fprintf(stderr, " (fatal)\n");
nerrors++;
stop();
}
usage() {
fprintf(stderr, "usage: %s -f [[low]-[high]] [testcollection]\n", prog);
nerrors++;
stop();
}

28
emtest/test.e Normal file
View file

@ -0,0 +1,28 @@
#define WS EM_WSIZE
#define PS EM_PSIZE
#include "test.h"
mes 2,WS,PS
mes 1
mes 4,300
.000
con "tst000"
exp $m_a_i_n
pro $m_a_i_n,0
loc 123
loc -98
; TEST 000: empty
fil .000
loc -98
bne *1
loc 123
bne *1
lin 0
nop
loc 0
ret WS
1
lin 1
nop
loc 1
ret WS
end

1
emtest/test.h Normal file
View file

@ -0,0 +1 @@
#define W2S 2*EM_WSIZE

3590
emtest/tests Normal file

File diff suppressed because it is too large Load diff