diff --git a/flipjump/stl/bit/div.fj b/flipjump/stl/bit/div.fj index 3d22f3c..173aa08 100644 --- a/flipjump/stl/bit/div.fj +++ b/flipjump/stl/bit/div.fj @@ -50,10 +50,13 @@ ns bit { // Space Complexity: n^2(11@+22) // if b==0: goto end (do nothing) // q = a/b (signed division) - // r = a%b (signed modulo - sign(r)==sign(b)) + // r = a%b (signed modulo - sign(r)==sign(a)) // @NOTE: a,b are SIGNED numbers. If you want a division with unsigned ints, use the div macro. // @NOTE: this division implementation is WASTEFUL in space, yet saves running time, compared to div_loop. - // @NOTE: For a faster division see hex.div. + // + // @NOTE: There is a better version: This one is slow, big, and doesn't error on b==0. + // Also it supports only one convention for the sign of the reminder. + // For a faster & better division see hex.div, hex.idiv. // q,a,b,r are bit[:n]. def idiv n, a, b, q, r @ negative_a, negative_b, one_negative, neg_b_1, do_div, neg_b_2, neg_ans, end { .mov negative_a, a+dw*(n-1) @@ -98,14 +101,16 @@ ns bit { // r = a%b (unsigned modulo) // @NOTE: a,b are UNSIGNED numbers. If you want a division with signed ints, use the idiv macro. // @NOTE: this division implementation is WASTEFUL in space, yet saves running time, compared to div_loop. - // @NOTE: For a faster division see hex.div. + // + // @NOTE: There is a better version: This one is slow, big, and doesn't error on b==0. + // For a faster & better division see hex.div, hex.idiv. // q,a,b,r are bit[:n]. def div n, a, b, q, r @ Q, R, end { .if0 n, b, end .zero 2*n, R .zero n, Q - rep(n, i) div.div_step n, a+(n-1-i)*dw, b, R+(n-1-i)*dw, Q+(n-1-i)*dw + rep(n, i) .div.div_step n, a+(n-1-i)*dw, b, R+(n-1-i)*dw, Q+(n-1-i)*dw .mov n, r, R .mov n, q, Q @@ -114,7 +119,7 @@ ns bit { R: .vec 2*n Q: - var n + .vec n end: } ns div { @@ -141,10 +146,13 @@ ns bit { // Space Complexity: n(37@+58) // if b==0: goto end (do nothing) // q = a/b (signed division) - // r = a%b (signed modulo - sign(r)==sign(b)) + // r = a%b (signed modulo - sign(r)==sign(a)) // @NOTE: a,b are SIGNED numbers. If you want a division with unsigned ints, use the div_loop macro. // @NOTE: this division implementation saves space, yet is slower, compared to div. - // @NOTE: For a faster division see hex.div. + // + // @NOTE: There is a better version: This one is slow, big, and doesn't error on b==0. + // Also it supports only one convention for the sign of the reminder. + // For a faster & better division see hex.div, hex.idiv. // q,a,b,r are bit[:n]. def idiv_loop n, a, b, q, r @ negative_a, negative_b, one_negative, neg_b_1, do_div, neg_b_2, neg_ans, end { .mov negative_a, a+dw*(n-1) @@ -189,7 +197,9 @@ ns bit { // r = a%b (unsigned modulo) // @NOTE: a,b are UNSIGNED numbers. If you want a division with signed ints, use the idiv_loop macro. // @NOTE: this division implementation saves space, yet is slower, compared to div. - // @NOTE: For a faster division see hex.div. + // + // @NOTE: There is a better version: This one is slow, big, and doesn't error on b==0. + // For a faster division see hex.div, hex.idiv. // q,a,b,r are bit[:n]. def div_loop n, a, b, q, r @ loop, do_sub, loop_end, after_loop, A, Q, R, i, end { .if0 n, b, end diff --git a/programs/simple_math_checks/bit_div.fj b/programs/simple_math_checks/bit_div.fj new file mode 100644 index 0000000..dbaac34 --- /dev/null +++ b/programs/simple_math_checks/bit_div.fj @@ -0,0 +1,83 @@ +stl.startup + +test_generic_div 20, 12, 1, 8, div +test_generic_div 20, 12, 1, 8, div_loop + +test_generic_div 20, 12, 1, 8, idiv +test_generic_div 20, (0-12), (0-1), 8, idiv +test_generic_div (0-20), 12, (0-1), (0-8), idiv +test_generic_div (0-20), (0-12), 1, (0-8), idiv + +test_generic_div 20, 12, 1, 8, idiv_loop +test_generic_div 20, (0-12), (0-1), 8, idiv_loop +test_generic_div (0-20), 12, (0-1), (0-8), idiv_loop +test_generic_div (0-20), (0-12), 1, (0-8), idiv_loop + + +stl.loop + + +div: + bit.div 8, ah, bh, res, mod + stl.fret ret + +div_loop: + bit.div_loop 8, ah, bh, res, mod + stl.fret ret + +idiv: + bit.idiv 8, ah, bh, res, mod + stl.fret ret + +idiv_loop: + bit.idiv_loop 8, ah, bh, res, mod + stl.fret ret + + +res: bit.vec 8 +mod: bit.vec 8 +ah: bit.vec 8 +bh: bit.vec 8 +ret: 0;0 + +div0: + stl.output "0" + stl.fret ret + +def test_generic_div a, b, expected_res, expected_mod, idiv_label\ + @ res_bad, res_good, mod_bad, mod_good, check_mod, expected_res_var, expected_mod_var, a_var, b_var, end\ + < ah, bh, ret, res, mod { + bit.mov 8, ah, a_var + bit.mov 8, bh, b_var + stl.fcall idiv_label, ret + + bit.cmp 8, res, expected_res_var, res_bad, res_good, res_bad + res_good: + stl.output '=' + ;check_mod + res_bad: + stl.output '!' + ;check_mod + + check_mod: + bit.cmp 8, mod, expected_mod_var, mod_bad, mod_good, mod_bad + + mod_good: + stl.output '=' + ;end + mod_bad: + stl.output '!' + ;end + + expected_res_var: + bit.vec 8, expected_res + expected_mod_var: + bit.vec 8, expected_mod + a_var: + bit.vec 8, a + b_var: + bit.vec 8, b + + end: + stl.output '\n' +} diff --git a/tests/inout/simple_math_checks/bit_div.out b/tests/inout/simple_math_checks/bit_div.out new file mode 100644 index 0000000..c53791f --- /dev/null +++ b/tests/inout/simple_math_checks/bit_div.out @@ -0,0 +1,10 @@ +== +== +== +== +== +== +== +== +== +== diff --git a/tests/tests_tables/test_compile_slow.csv b/tests/tests_tables/test_compile_slow.csv index 33e05af..02d64a8 100644 --- a/tests/tests_tables/test_compile_slow.csv +++ b/tests/tests_tables/test_compile_slow.csv @@ -1,6 +1,7 @@ hex_func7, programs/func_tests/func7.fj,tests/compiled/func_tests/func7.fjm, 64,3,0, True,True shra, programs/simple_math_checks/shra.fj,tests/compiled/simple_math_checks/shra.fjm, 64,3,0, True,True +bit-div, programs/simple_math_checks/bit_div.fj,tests/compiled/simple_math_checks/bit_div.fjm, 64,3,0, True,True calc, programs/calc.fj,tests/compiled/calc.fjm, 64,3,0, True,True diff --git a/tests/tests_tables/test_run_slow.csv b/tests/tests_tables/test_run_slow.csv index e3fc2f1..ba5dd3e 100644 --- a/tests/tests_tables/test_run_slow.csv +++ b/tests/tests_tables/test_run_slow.csv @@ -1,6 +1,7 @@ hex_func7, tests/compiled/func_tests/func7.fjm, ,tests/inout/func_tests/func7.out, False,False shra, tests/compiled/simple_math_checks/shra.fjm, ,tests/inout/simple_math_checks/25equals.out, False,False +bit-div, tests/compiled/simple_math_checks/bit_div.fjm, ,tests/inout/simple_math_checks/bit_div.out, False,False calc1, tests/compiled/calc.fjm, tests/inout/calc_tests/calc1.in,tests/inout/calc_tests/calc1.out, False,False calc2, tests/compiled/calc.fjm, tests/inout/calc_tests/calc2.in,tests/inout/calc_tests/calc2.out, False,False