Subversion Repositories planix.SVN

Rev

Rev 26 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#!/bin/rc
echo '
cmp     in      in      retsign
magcmp  in      in      retsign
add     in      in      out
sub     in      in      out
magadd  in      in      out
magsub  in      in      out
and     in      in      out
bic     in      in      out
or      in      in      out
xor     in      in      out
not     in      out
left    in      int     out
right   in      int     out
asr     in      int     out
div_    in      in      out     out
' | sed 's/#.*//g' | awk '
BEGIN {
        print "#include <u.h>"
        print "#include <libc.h>"
        print "#include <mp.h>"
        print "#include \"dat.h\""
        print "#include \"fns.h\""
}
function initio()
{
        for(j=2;j<=NF;j++){
                if($j == "in")
                        printf "ldtomp(l%d, m%d);\n", j, j
                if($j == "out")
                        printf "mptarget(m%d);\n", j
        }
}
function fail0()
{
        printf "fprint(2, \"FAIL: mp%s(", $1
        first = 1
        for(j=2;j<=NF;j++){
                if(!first) printf ", "
                first = 0
                if($j == "in")
                        printf "%%L"
                if($j == "int")
                        printf "%%d"
                if($j == "out")
                        printf "out"
        }
        printf "): "
        if(test) printf "%s: ", test
}
function fail1()
{
        for(j=2;j<=NF;j++){
                if($j == "in")
                        printf ", l%d", j
                if($j == "int")
                        printf ", i%d", j
        }
}
function testarg(ref,i,t)
{
        if(t == "in"){
                printf "if(!ldmpeq(l%d, m%d)){\n", ref, i
                fail0()
                printf "arg %d: input corrupted\\n\"", ref - 1
                fail1()
                printf ");\n"
                printf "fail=1;\n}\n"
        }
        if(t == "out"){
                printf "if(m%d->top == 0 && m%d->sign < 0){\n", i, i
                fail0()
                printf "arg %d: got -0, shouldn''t happen\\n\"", ref - 1
                fail1()
                printf ");\n"
                print "fail=1;"
                printf "}else if(m%d->top != 0 && m%d->p[m%d->top - 1] == 0){\n", i, i, i
                fail0()
                printf "arg %d: got denormalised result\\n\"", ref - 1
                fail1()
                printf ");\n"
                print "fail=1;"
                printf "}else if(!ldmpeq(l%d, m%d)){\n", ref, i
                fail0()
                printf "arg %d: got %%#B, expected %%L\\n\"", ref - 1
                fail1()
                printf ", m%d, l%d);\n", i, ref
                printf "fail=1;\n"
                printf "}\n"
        }
}

NF > 0 && !($NF ~ /^ret/) {
        printf "void ld%s(", $1
        for(i=2;i<=NF;i++){
                if($i == "in" || $i == "out")
                        printf "ldint *"
                if($i == "int")
                        printf "int"
                if(i<NF) printf ", "
        }
        printf ");\n"

        printf "void\ntest%s(void)\n{\n", $1
        print "int fail=0;"
        for(i=2;i<=NF;i++){
                if($i == "in" || $i == "out"){
                        printf "ldint *l%d = ldnew(0);\n", i
                        printf "mpint *m%d = mpnew(0);\n", i
                }
                if($i == "int" || $i == "in")
                        printf "int i%d;\n", i
        }
        for(i=2;i<=NF;i++){
                if($i == "in"){
                        printf "for(i%d=0;i%d<NTEST;i%d++){\n", i, i, i
                        printf "testgen(i%d, l%d);\n", i, i
                }
                if($i == "int")
                        printf "for(i%d=-128;i%d<=128;i%d++){\n", i, i, i
        }
        
        test=""
        printf "ld%s(", $1
        for(i=2;i<=NF;i++){
                if($i == "in" || $i == "out")
                        printf "l%d", i
                if($i == "int")
                        printf "i%d", i
                if(i<NF) printf ", "
        }
        printf ");\n"
        initio()

        printf "mp%s(", $1
        for(i=2;i<=NF;i++){
                if($i == "in" || $i == "out")
                        printf "m%d", i
                if($i == "int")
                        printf "i%d", i
                if(i<NF) printf ", "
        }
        printf ");\n"
        
        for(i=2;i<=NF;i++)
                testarg(i, i, $i)
        
        for(i=2;i<=NF;i++){
                if($i != "out") continue
                for(k=2;k<=NF;k++){
                        if($k != "in") continue
                        test="alias "(i-1)" and "(k-1)
                        initio()
                        printf "mp%s(", $1
                        for(l=2;l<=NF;l++){
                                if(l == i){
                                        printf "m%d", k
                                }else{
                                        if($l == "in" || $l == "out")
                                                printf "m%d", l
                                        if($l == "int")
                                                printf "i%d", l
                                }
                                if(l<NF) printf ", "
                        }
                        printf ");\n"
                        for(l=2;l<=NF;l++)
                                if(l != k && l != i)
                                        testarg(l, l, $l)
                        testarg(i, k, "out")
                }
        }

        for(i=2;i<=NF;i++)
                if($i == "in" || $i == "int")
                        printf "}\n"
        for(i=2;i<=NF;i++)
                if($i == "in" || $i == "out"){
                        printf "ldfree(l%d);\nmpfree(m%d);\n", i, i
                }
        printf "if(!fail) fprint(2, \"mp%s: passed\\n\");\n", $1
        printf "}\n"
        tests[ntests++] = $1
        next
}
NF > 0 {
        sign=$NF=="retsign";
        NF--
        printf "int ld%s(", $1
        for(i=2;i<=NF;i++){
                if($i == "in" || $i == "out")
                        printf "ldint *"
                if($i == "int")
                        printf "int"
                if(i<NF) printf ", "
        }
        printf ");\n"

        printf "void\ntest%s(void)\n{\n", $1
        print "int fail=0;"
        print "int a, b;"
        for(i=2;i<=NF;i++){
                if($i == "in" || $i == "out"){
                        printf "ldint *l%d = ldnew(0);\n", i
                        printf "mpint *m%d = mpnew(0);\n", i
                }
                if($i == "int" || $i == "in")
                        printf "int i%d;\n", i
        }
        for(i=2;i<=NF;i++){
                if($i == "in"){
                        printf "for(i%d=0;i%d<NTEST;i%d++){\n", i, i, i
                        printf "testgen(i%d, l%d);\n", i, i
                }
                if($i == "int")
                        printf "for(i%d=-128;i%d<=128;i%d++){\n", i, i, i
        }
        
        test=""
        printf "a=ld%s(", $1
        for(i=2;i<=NF;i++){
                if($i == "in" || $i == "out")
                        printf "l%d", i
                if($i == "int")
                        printf "i%d", i
                if(i<NF) printf ", "
        }
        printf ");\n"
        initio()

        printf "b=mp%s(", $1
        for(i=2;i<=NF;i++){
                if($i == "in" || $i == "out")
                        printf "m%d", i
                if($i == "int")
                        printf "i%d", i
                if(i<NF) printf ", "
        }
        printf ");\n"

        if(sign) printf "if(b<0) b=-1;\nif(b>0) b=1;\n"
        printf "if(a != b){\n", ref, i
        fail0()
        printf "return value: got %%d, expected %%d\\n\""
        fail1()
        printf ", b, a);\n"
        printf "fail=1;\n"
        printf "}\n"
        
        for(i=2;i<=NF;i++)
                testarg(i, i, $i)
        
        for(i=2;i<=NF;i++)
                if($i == "in" || $i == "int")
                        printf "}\n"
        for(i=2;i<=NF;i++)
                if($i == "in" || $i == "out"){
                        printf "ldfree(l%d);\nmpfree(m%d);\n", i, i
                }
        printf "if(!fail) fprint(2, \"mp%s: passed\\n\");\n", $1
        printf "}\n"
        tests[ntests++] = $1
}
END {
        printf "void\ntests()\n{\n"
        for(i = 0; i < ntests; i++)
                printf "test%s();\n", tests[i]
        printf "}\n"
}
' | awk '
/^[     ]*}/ { ind = substr(ind, 2) }
{ printf "%s%s\n", ind, $0 }
/{ *$/ { ind = "\t" ind }
'