diff --git a/math32.tal b/math32.tal index 17744e4..523bd77 100644 --- a/math32.tal +++ b/math32.tal @@ -22,6 +22,8 @@ ( program ) |0100 +( #1234 #5678 ;emit-long JSR2 NEWLINE + #0000 #0009 #0000 #0003 ;div32 JSR2 ;emit-long JSR2 NEWLINE ) ;test-interact .Console/vector DEO2 BRK ( bitcount: number of bits needed to represent number ) @@ -339,37 +341,55 @@ RTN [ &y0 $2 &y1 $2 ] [ &z0 $2 &z1 $2 ] +@div32 ( x** y** -> q** ) + ( store y and x for repeated use ) + ;div32/div1 STA2 ;div32/div0 STA2 ( y -> div ) + ;div32/rem1 STA2 ;div32/rem0 STA2 ( x -> rem ) -@divmod32-by-32 ( x** y** -> q** r** ) - ,&div1 STR2 ,&div0 STR2 ( y -> div ) - ,&rem1 STR2 ,&rem0 STR2 ( x -> rem ) - #0000 ,&quo1 STR2 #0000 ,&quo0 STR2 ( 0 -> quo ) - ,&rem0 LDR2 ,&rem1 LDR2 ;bitcount32 JSR2 ( rbits^ ) - ,&div0 LDR2 ,&div1 LDR2 ;bitcount32 JSR2 ( rbits^ dbits^ ) - SUBk ,&shift STR ( rbits-dbits -> shift ) - ,&div0 LDR2 ,&div1 LDR2 ,&shift LDR ;left-shift JSR2 ( div<= y so the answer is >= 1 ) + ¬-zero + #0000 ;div32/quo0 STA2 #0000 ;div32/quo1 STA2 ( 0 -> quo ) + + ( bitcount[x] - bitcount[y] determines the largest multiple of y to try ) + ;div32/rem0 LDA2 ;div32/rem1 LDA2 ;bitcount32 JSR2 ( rbits^ ) + ;div32/div0 LDA2 ;div32/div1 LDA2 ;bitcount32 JSR2 ( rbits^ dbits^ ) + SUB ( shift=rbits-dits ) + #00 DUP2 ( shift 0 shift 0 ) + + ( 1< cur ) + #0000 #0001 ROT2 POP + ;left-shift JSR2 ;div32/cur1 STA2 ;div32/cur0 STA2 + + ( div< div ) + ;div32/div0 LDA2 ;div32/div1 LDA2 ROT2 POP + ;left-shift JSR2 ;div32/div1 STA2 ;div32/div0 STA2 + + &loop + ( if rem >= the current divisor, we can subtract it and add to quotient ) + ,&rem0 LDR2 ,&rem1 LDR2 ,&div0 LDR2 ,&div1 LDR2 ;lt32 JSR2 ( rem= div, then we have found a multiple of y that divides x ) + ,&rem0 LDR2 ,&rem1 LDR2 ,&div0 LDR2 ,&div1 LDR2 ;sub32 JSR2 ,&rem1 STR2 ,&rem0 STR2 ( rem -= div ) + ,&quo0 LDR2 ,&quo1 LDR2 ,&cur0 LDR2 ,&cur1 LDR2 ;add32 JSR2 ,&quo1 STR2 ,&quo0 STR2 ( quo += cur ) + + &rem-lt + ,&div0 LDR2 ,&div1 LDR2 #01 ;right-shift JSR2 ,&div1 STR2 ,&div0 STR2 ( div >>= 1 ) + ,&cur0 LDR2 ,&cur1 LDR2 #01 ;right-shift JSR2 ,&cur1 STR2 ,&cur0 STR2 ( cur >>= 1 ) + ,&cur0 LDR2 ,&cur1 LDR2 ;non-zero32 JSR2 ,&loop JCN ( if cur>0, loop. else we're done ) + ,&quo0 LDR2 ,&quo1 LDR2 ( TODO: consider making this divmod32 ) RTN [ &div0 $2 &div1 $2 &rem0 $2 &rem1 $2 &quo0 $2 &quo1 $2 - &shift $1 ] - -@divmod16-by-8 ( x* y^ -> q* r^ ) - DUP ,&y STR - ROT SWP ( x1 x0 y ) - DIVk ( x1 x0 y q0 ) - DUP ,&q0 STR ( x1 x0 y q0 ) - MUL SUB ( x1 r=x0-y*q0 ) - SWP #00 ,&y LDR ( r x1 00 y ) - DIV2k ( rx1 00y q1 ) - DUP2 ROT2 MUL2 ( rx1 q1 y*q1 ) - ROT2 SWP2 SUB2 ( q1 rr=rx1-y*q1 ) - SWP POP ( q1 rrlo ) - ROT POP ( q1lo rrlo ) - ,&q0 LDR TOR -RTN -[ &y $1 &q0 $1 ] + &cur0 $2 &cur1 $2 ] ( testing ) @@ -403,6 +423,7 @@ RTN ;buf LDA LIT '+ EQU ;test-add32 JCN2 ;buf LDA LIT '* EQU ;test-mul32 JCN2 ;buf LDA LIT '- EQU ;test-sub32 JCN2 + ;buf LDA LIT '/ EQU ;test-div32 JCN2 ;buf LDA LIT 'L EQU ;test-left-shift JCN2 ;buf LDA LIT 'R EQU ;test-right-shift JCN2 ;buf LDA LIT 'B EQU ;test-bitcount32 JCN2 @@ -473,6 +494,7 @@ RTN @test-add32 ;add32 ;binary-32-test JMP2 @test-mul32 ;mul32 ;binary-32-test JMP2 @test-sub32 ;sub32 ;binary-32-test JMP2 +@test-div32 ;div32 ;binary-32-test JMP2 @test-left-shift ;left-shift ;binary-32-8-32-test JMP2 @test-right-shift ;right-shift ;binary-32-8-32-test JMP2 @test-bitcount32 ;bitcount32 ;unary-32-8-test JMP2 @@ -496,9 +518,9 @@ RTN SWP EMIT-BYTE EMIT-BYTE RTN -@emit-short ( x* -> ) - SWP EMIT-BYTE EMIT-BYTE -RTN +( @emit-short ( x* -> ) +( SWP EMIT-BYTE EMIT-BYTE +RTN ) @emit-byte ( x^ -> ) EMIT-BYTE diff --git a/tester.py b/tester.py index 67d362a..1174fd6 100644 --- a/tester.py +++ b/tester.py @@ -62,6 +62,7 @@ def main(): test(p, trials, b'+', [('x', u32), ('y', u32)], u32, lambda x, y: x + y) test(p, trials, b'-', [('x', u32), ('y', u32)], u32, lambda x, y: x - y) test(p, trials, b'*', [('x', u32), ('y', u32)], u32, lambda x, y: x * y) + test(p, trials, b'/', [('x', u32), ('y', u32)], u32, lambda x, y: x // y) test(p, trials, b'L', [('x', u32), ('y', u5)], u32, lambda x, y: x << y) test(p, trials, b'R', [('x', u32), ('y', u5)], u32, lambda x, y: x >> y) test(p, trials, b'B', [('x', u32)], u8, bitcount)