From 5938805c2de83e0c5fc97072c9013f1c88cc2853 Mon Sep 17 00:00:00 2001 From: d6 Date: Wed, 29 Dec 2021 16:17:01 -0500 Subject: [PATCH] implement mod32, divmod32, etc. --- math32.tal | 65 ++++++++++++++++++++++++++++++++----------------- test-math32.tal | 2 ++ tester.py | 1 + 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/math32.tal b/math32.tal index 28e76b1..67f4037 100644 --- a/math32.tal +++ b/math32.tal @@ -24,7 +24,9 @@ ( sub32 x** y** -> z** x - y ) ( mul16 x* y* -> z** x * y ) ( mul32 x** y** -> z** x * y ) -( div32 x** y** -> z** x / y ) +( div32 x** y** -> q** x / y ) +( mod32 x** y** -> r** x % y ) +( divmod32 x** y** -> q** r** x / y, x % y ) ( negate32 x** -> z** -x ) ( lshift32 x** n^ -> z** x< z** x>>n ) @@ -49,7 +51,7 @@ ( ) ( - shared memory, 16 bytes ) ( - mul32 memory, 12 bytes ) -( - div32 memory, 16 bytes ) +( - _divmod32 memory, 16 bytes ) %DEBUG { #ff #0e DEO } %RTN { JMP2r } @@ -331,7 +333,6 @@ ,&x1 STR2 ,&x0 STR2 ( save xlo, xhi ) ,&y1 LDR2 ,&x1 LDR2 ;mul16 JSR2 ( [x1*y1] ) ,&z1 STR2 ,&z0 STR2 ( sum = x1*y1, save zlo, zhi ) - ,&y1 LDR2 ,&x0 LDR2 MUL2 ( [x0*y1]<<16 ) ,&y0 LDR2 ,&x1 LDR2 MUL2 ( [x1*y0]<<16 ) ( [x0*y0]<<32 will completely overflow ) @@ -342,43 +343,66 @@ &y0 $2 &y1 $2 &z0 $2 &z1 $2 ] -( x / y ) @div32 ( x** y** -> q** ) + ;_divmod32 JSR2 + ;_divmod32/quo0 LDA2 ;_divmod32/quo1 LDA2 + RTN + +@mod32 ( x** y** -> r** ) + ;_divmod32 JSR2 + ;_divmod32/rem0 LDA2 ;_divmod32/rem1 LDA2 + RTN + +@divmod32 ( x** y** -> q** r** ) + ;_divmod32 JSR2 + ;_divmod32/quo0 LDA2 ;_divmod32/quo1 LDA2 + ;_divmod32/rem0 LDA2 ;_divmod32/rem1 LDA2 + RTN + +( calculate and store x / y and x % y ) +@_divmod32 ( x** y** -> ) ( store y and x for repeated use ) - ;div32/div1 STA2 ;div32/div0 STA2 ( y -> div ) - ;div32/rem1 STA2 ;div32/rem0 STA2 ( x -> rem ) + ,&div1 STR2 ,&div0 STR2 ( y -> div ) + ,&rem1 STR2 ,&rem0 STR2 ( x -> rem ) ( if x < y then the answer is 0 ) - ;div32/rem0 LDA2 ;div32/rem1 LDA2 - ;div32/div0 LDA2 ;div32/div1 LDA2 + ,&rem0 LDR2 ,&rem1 LDR2 + ,&div0 LDR2 ,&div1 LDR2 ;lt32 JSR2 ,&is-zero JCN ,¬-zero JMP &is-zero - #0000 #0000 RTN + #0000 ,&quo0 STR2 #0000 ,&quo1 STR2 RTN ( x >= y so the answer is >= 1 ) ¬-zero - #0000 ;div32/quo0 STA2 #0000 ;div32/quo1 STA2 ( 0 -> quo ) + #0000 ,&quo0 STR2 #0000 ,&quo1 STR2 ( 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^ ) + ,&rem0 LDR2 ,&rem1 LDR2 ;bitcount32 JSR2 ( rbits^ ) + ,&div0 LDR2 ,&div1 LDR2 ;bitcount32 JSR2 ( rbits^ dbits^ ) SUB ( shift=rbits-dits ) #00 DUP2 ( shift 0 shift 0 ) ( 1< cur ) #0000 #0001 ROT2 POP - ;lshift32 JSR2 ;div32/cur1 STA2 ;div32/cur0 STA2 + ;lshift32 JSR2 ,&cur1 STR2 ,&cur0 STR2 ( div< div ) - ;div32/div0 LDA2 ;div32/div1 LDA2 ROT2 POP - ;lshift32 JSR2 ;div32/div1 STA2 ;div32/div0 STA2 + ,&div0 LDR2 ,&div1 LDR2 ROT2 POP + ;lshift32 JSR2 ,&div1 STR2 ,&div0 STR2 - &loop + ,&loop JMP + + [ &div0 $2 &div1 $2 + &rem0 $2 &rem1 $2 + &quo0 $2 &quo1 $2 + &cur0 $2 &cur1 $2 ] + + &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 ) + ( since rem >= div, 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 ) @@ -386,9 +410,4 @@ ,&div0 LDR2 ,&div1 LDR2 #01 ;rshift32 JSR2 ,&div1 STR2 ,&div0 STR2 ( div >>= 1 ) ,&cur0 LDR2 ,&cur1 LDR2 #01 ;rshift32 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 - &cur0 $2 &cur1 $2 ] diff --git a/test-math32.tal b/test-math32.tal index 8bdd3c7..8a1d952 100644 --- a/test-math32.tal +++ b/test-math32.tal @@ -52,6 +52,7 @@ RTN ;buf LDA LIT '* EQU ;test-mul32 JCN2 ;buf LDA LIT '- EQU ;test-sub32 JCN2 ;buf LDA LIT '/ EQU ;test-div32 JCN2 + ;buf LDA LIT '% EQU ;test-mod32 JCN2 ;buf LDA LIT 'L EQU ;test-lshift32 JCN2 ;buf LDA LIT 'R EQU ;test-rshift32 JCN2 ;buf LDA LIT 'B EQU ;test-bitcount32 JCN2 @@ -123,6 +124,7 @@ RTN @test-mul32 ;mul32 ;binary-32-test JMP2 @test-sub32 ;sub32 ;binary-32-test JMP2 @test-div32 ;div32 ;binary-32-test JMP2 +@test-mod32 ;mod32 ;binary-32-test JMP2 @test-lshift32 ;lshift32 ;binary-32-8-32-test JMP2 @test-rshift32 ;rshift32 ;binary-32-8-32-test JMP2 @test-bitcount32 ;bitcount32 ;unary-32-8-test JMP2 diff --git a/tester.py b/tester.py index e9cbbe8..e0bcaa6 100644 --- a/tester.py +++ b/tester.py @@ -63,6 +63,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)