diff --git a/math32.tal b/math32.tal index 23181ac..603bae8 100644 --- a/math32.tal +++ b/math32.tal @@ -23,68 +23,7 @@ ( program ) |0100 - -( #0000 ;pos STA2 ) ;interact .Console/vector DEO2 - BRK - -( #1000 #03 ;divmod16-by-8 JSR2 ;emit-short-byte JSR2 NEWLINE - NEWLINE - - #1124 #1244 #01 ;left-shift JSR2 ;emit-long JSR2 NEWLINE - #1124 #1244 #02 ;left-shift JSR2 ;emit-long JSR2 NEWLINE - #1124 #1244 #08 ;left-shift JSR2 ;emit-long JSR2 NEWLINE - #1124 #1244 #0f ;left-shift JSR2 ;emit-long JSR2 NEWLINE - #1124 #1244 #10 ;left-shift JSR2 ;emit-long JSR2 NEWLINE - #1124 #1244 #13 ;left-shift JSR2 ;emit-long JSR2 NEWLINE - #1124 #1244 #17 ;left-shift JSR2 ;emit-long JSR2 NEWLINE - #1124 #1244 #18 ;left-shift JSR2 ;emit-long JSR2 NEWLINE - #1124 #1244 #19 ;left-shift JSR2 ;emit-long JSR2 NEWLINE - #0000 #0001 #1f ;left-shift JSR2 ;emit-long JSR2 NEWLINE - #0000 #0001 #20 ;left-shift JSR2 ;emit-long JSR2 NEWLINE - NEWLINE - - #0000 #0000 ;bitcount32 JSR2 ;emit-byte JSR2 NEWLINE - #0000 #0100 ;bitcount32 JSR2 ;emit-byte JSR2 NEWLINE - #0001 #0000 ;bitcount32 JSR2 ;emit-byte JSR2 NEWLINE - #0010 #0000 ;bitcount32 JSR2 ;emit-byte JSR2 NEWLINE - #1000 #0000 ;bitcount32 JSR2 ;emit-byte JSR2 NEWLINE - #f000 #0000 ;bitcount32 JSR2 ;emit-byte JSR2 NEWLINE - NEWLINE - - #ffff #ffff #2a ;mul16 ;emit-short ;test16 JSR2 - #0001 #ffff #2a ;mul16 ;emit-short ;test16 JSR2 - #ffff #0001 #2a ;mul16 ;emit-short ;test16 JSR2 - #00ff #0001 #2a ;mul16 ;emit-short ;test16 JSR2 - NEWLINE - - #ffff #ffff #ffff #ffff #2a ;mul32 ;emit-long ;test32 JSR2 - #0000 #0001 #ffff #ffff #2a ;mul32 ;emit-long ;test32 JSR2 - #0000 #0002 #0000 #ffff #2a ;mul32 ;emit-long ;test32 JSR2 - #0001 #2345 #0034 #5678 #2a ;mul32 ;emit-long ;test32 JSR2 - NEWLINE - - X Y #2b ;add32 ;emit-long ;test32 JSR2 - Z Y #2b ;add32 ;emit-long ;test32 JSR2 - #fedc #0000 #1234 #0000 #2b ;add32 ;emit-long ;test32 JSR2 - #fedc #0000 #0000 #0000 #2b ;add32 ;emit-long ;test32 JSR2 - #0000 #0000 #0000 #0000 #2b ;add32 ;emit-long ;test32 JSR2 - NEWLINE - - #1234 #1234 #0000 #0001 #2d ;sub32 ;emit-long ;test32 JSR2 - #1234 #1234 #0000 #1234 #2d ;sub32 ;emit-long ;test32 JSR2 - #1234 #1234 #1234 #0001 #2d ;sub32 ;emit-long ;test32 JSR2 - #1234 #1234 #1000 #0000 #2d ;sub32 ;emit-long ;test32 JSR2 - #1234 #1234 #ffff #ffff #2d ;sub32 ;emit-long ;test32 JSR2 - NEWLINE - - X Y #26 ;and32 ;emit-long ;test32 JSR2 - X Y #7c ;or32 ;emit-long ;test32 JSR2 - X Y #5e ;xor32 ;emit-long ;test32 JSR2 - X Y #3d ;eq32 ;emit-byte ;test32 JSR2 - Y Y #3d ;eq32 ;emit-byte ;test32 JSR2 - X Y #7e ;ne32 ;emit-byte ;test32 JSR2 - X X #7e ;ne32 ;emit-byte ;test32 JSR2 ) BRK ( e.g. #31 #33 -> #13 ) @@ -103,6 +42,10 @@ RTN @buf $24 @pos $2 +@read-byte ( addr* -> x^ ) + LDA2 ;parse-byte JSR2 +RTN + @read-long ( addr* -> x** ) DUP2 ,&loc STR2 LDA2 ;parse-byte JSR2 ,&loc LDR2 #0002 ADD2 LDA2 ;parse-byte JSR2 @@ -125,28 +68,33 @@ RTN ;buf LDA LIT '* EQU ;test-mul32 JCN2 ;buf LDA LIT '- EQU ;test-sub32 JCN2 ;buf LDA LIT 'L EQU ;test-left-shift JCN2 + ;buf LDA LIT 'B EQU ;test-bitcount32 JCN2 + ;buf LDA LIT '& EQU ;test-and32 JCN2 + ;buf LDA LIT '| EQU ;test-or32 JCN2 + ;buf LDA LIT '^ EQU ;test-xor32 JCN2 + ;buf LDA LIT '~ EQU ;test-complement32 JCN2 + ;buf LDA LIT 'N EQU ;test-negate32 JCN2 LIT '? EMIT NEWLINE RESET-POS BRK -@test-add32 - ( format: "+ xxxxxxxx yyyyyyyy" ) +( format: ". xxxxxxxx" ) +%UNARY-32-TEST { ;buf #0002 ADD2 ;read-long JSR2 - ;buf #000b ADD2 ;read-long JSR2 - ;add32 JSR2 ;emit-long JSR2 + ROT2 JSR2 ;emit-long JSR2 NEWLINE RESET-POS BRK +} -@test-mul32 - ( format: "+ xxxxxxxx yyyyyyyy" ) +( format: ". xxxxxxxx yyyyyyyy" ) +%BINARY-32-TEST { ;buf #0002 ADD2 ;read-long JSR2 + ROT2 ;buf #000b ADD2 ;read-long JSR2 - ;mul32 JSR2 ;emit-long JSR2 + ROT2 JSR2 ;emit-long JSR2 NEWLINE RESET-POS BRK +} -@test-sub32 - ( format: "+ xxxxxxxx yyyyyyyy" ) - ;buf #0002 ADD2 ;read-long JSR2 - ;buf #000b ADD2 ;read-long JSR2 - ;sub32 JSR2 ;emit-long JSR2 - NEWLINE RESET-POS BRK +@test-add32 ;add32 BINARY-32-TEST +@test-mul32 ;mul32 BINARY-32-TEST +@test-sub32 ;sub32 BINARY-32-TEST @test-left-shift ( format: "+ xxxxxxxx yy" ) @@ -155,45 +103,17 @@ RTN ;left-shift JSR2 ;emit-long JSR2 NEWLINE RESET-POS BRK -@test16 ( x* y* symbol^ test-addr* emit-addr* -> ) - ,&emitaddr STR2 - ,&testaddr STR2 - ,&testsym STR - ,&y STR2 - ,&x STR2 - ,&x LDR2 ;emit-short JSR2 - SPACE ,&testsym LDR EMIT SPACE - ,&y LDR2 ;emit-short JSR2 - SPACE #3d EMIT SPACE - ,&x LDR2 ,&y LDR2 - ,&testaddr LDR2 JSR2 - ,&emitaddr LDR2 JSR2 NEWLINE -RTN -&testsym $1 -&testaddr $2 -&emitaddr $2 -&x $2 &y $2 +@test-bitcount32 + ( format: "B xxxxxxxx" ) + ;buf #0002 ADD2 ;read-long JSR2 + ;bitcount32 JSR2 ;emit-byte JSR2 + NEWLINE RESET-POS BRK -@test32 ( x** y** symbol^ test-addr* emit-addr* -> ) - ,&emitaddr STR2 - ,&testaddr STR2 - ,&testsym STR - ,&ylo STR2 ,&yhi STR2 - ,&xlo STR2 ,&xhi STR2 - ,&xhi LDR2 ,&xlo LDR2 ;emit-long JSR2 - SPACE ,&testsym LDR EMIT SPACE - ,&yhi LDR2 ,&ylo LDR2 ;emit-long JSR2 - SPACE #3d EMIT SPACE - ,&xhi LDR2 ,&xlo LDR2 - ,&yhi LDR2 ,&ylo LDR2 - ,&testaddr LDR2 JSR2 - ,&emitaddr LDR2 JSR2 NEWLINE -RTN -&testsym $1 -&testaddr $2 -&emitaddr $2 -&xhi $2 &xlo $2 -&yhi $2 &ylo $2 +@test-and32 ;and32 BINARY-32-TEST +@test-or32 ;or32 BINARY-32-TEST +@test-xor32 ;xor32 BINARY-32-TEST +@test-complement32 ;complement32 UNARY-32-TEST +@test-negate32 ;negate32 UNARY-32-TEST @bitcount8 ( x^ -> n^ ) #00 SWP ( n x ) @@ -285,10 +205,10 @@ RTN DUP #18 LTH ;left-shift2 JCN2 ( x n ) ;left-shift3 JMP2 ( x n ) RTN -[ &z0 $1 &z1 $1 &z2 $1 &z3 $1 ] ( shift left by 0-7 bits ) @left-shift0 ( x** n^ -> x< r ) SWP SWP2 SWP ( x3 x2 x1 x0 ) @@ -309,6 +229,7 @@ RTN ( shift left by 8-15 bits ) @left-shift1 ( x** n^ -> x< r ) SWP SWP2 SWP POP ( x3 x2 x1 ) @@ -326,6 +247,7 @@ RTN ( shift left by 16-23 bits ) @left-shift2 ( x** n^ -> x< r ) SWP2 POP2 SWP ( x3 x2 ) diff --git a/tester.py b/tester.py index 9ad6441..c5842ec 100644 --- a/tester.py +++ b/tester.py @@ -4,45 +4,73 @@ from os import environ from subprocess import Popen, PIPE from random import randint -ubyte = {'sz': 1 << 8, 'fmt': b'%02x'} -ushort = {'sz': 1 << 16, 'fmt': b'%04x'} -ulong = {'sz': 1 << 32, 'fmt': b'%08x'} +u5 = {'sz': 1 << 5, 'fmt': b'%02x'} +u8 = {'sz': 1 << 8, 'fmt': b'%02x'} +u16 = {'sz': 1 << 16, 'fmt': b'%04x'} +u32 = {'sz': 1 << 32, 'fmt': b'%08x'} -def u32(x): - return x % 4294967296 +def fmt(gx, x): + return gx['fmt'].decode('utf-8') % (x % gx['sz']) -def case(p, x, y, sym, f): - p.stdin.write(b'%s %08x %08x\n' % (sym, x, y)) +def testcase(p, sym, args, out, f): + xs = [randint(0, a[1]['sz'] - 1) for a in args] + p.stdin.write(sym) + for i in range(0, len(args)): + x = xs[i] + g = args[i][1] + p.stdin.write(b' ') + p.stdin.write(g['fmt'] % x) + p.stdin.write(b'\n') p.stdin.flush() got = p.stdout.readline().strip().decode('utf-8') - expected = '%08x' % u32(f(x, y)) - return got == expected + z = f(*xs) + expected = fmt(out, z) + if got == expected: + return None + else: + res = {'got': got, 'expected': expected} + for (name, x) in args: res[name] = x + return res -def test(p, runs, sym, f): +def test(p, runs, sym, args, out, f): fails = 0 cases = [] maximum = (1 << 32) - 1 for i in range(0, runs): - x = randint(0, maximum) - y = randint(0, maximum) - ok = case(p, x, y, sym, f) - if not ok: + case = testcase(p, sym, args, out, f) + if case is not None: fails += 1 - cases.append((x, y)) + cases.append(case) name = sym.decode('utf-8') if fails == 0: print('%s passed %d runs' % (name, runs)) else: print('%s failed %d/%d runs (%r)' % (name, fails, runs, cases)) + +def pipe(): + cli = environ['HOME'] + '/w/uxn/bin/uxncli' + return Popen([cli, 'run.rom'], stdin=PIPE, stdout=PIPE) + +def bitcount(x): + n = 0 + while x > 0: + n += 1 + x = x >> 1 + return n def main(): - home = environ['HOME'] - p = Popen([home + '/w/uxn/bin/uxncli', 'run.rom'], stdin=PIPE, stdout=PIPE) - runs = 1000 - test(p, runs, b'+', lambda x, y: x + y) - test(p, runs, b'-', lambda x, y: x - y) - test(p, runs, b'*', lambda x, y: x * y) - #test(p, runs, b'L', lambda x, y: x << y) + runs = 100 + p = pipe() + test(p, runs, b'+', [('x', u32), ('y', u32)], u32, lambda x, y: x + y) + test(p, runs, b'-', [('x', u32), ('y', u32)], u32, lambda x, y: x - y) + test(p, runs, b'*', [('x', u32), ('y', u32)], u32, lambda x, y: x * y) + test(p, runs, b'L', [('x', u32), ('y', u5)], u32, lambda x, y: x << y) + test(p, runs, b'B', [('x', u32)], u8, bitcount) + test(p, runs, b'&', [('x', u32), ('y', u32)], u32, lambda x, y: x & y) + test(p, runs, b'|', [('x', u32), ('y', u32)], u32, lambda x, y: x | y) + test(p, runs, b'^', [('x', u32), ('y', u32)], u32, lambda x, y: x ^ y) + test(p, runs, b'~', [('x', u32)], u32, lambda x: ~x) + test(p, runs, b'N', [('x', u32)], u32, lambda x: -x) p.stdin.close() p.stdout.close()