diff --git a/.github/workflows/check_float_tests.yml b/.github/workflows/check_float_tests.yml new file mode 100644 index 000000000..dd22ca556 --- /dev/null +++ b/.github/workflows/check_float_tests.yml @@ -0,0 +1,31 @@ +name: Check floating-point tests + +on: + push: + paths: + - .github/workflows/check_float_tests.yml + - tools/check_float_test_names.py + - src/rp2_common/pico_float/include/pico/float.h + - src/rp2_common/pico_double/include/pico/double.h + - test/pico_float_test/custom_float_funcs_test.c + - test/pico_float_test/custom_double_funcs_test.c + pull_request: + paths: + - .github/workflows/check_float_tests.yml + - tools/check_float_test_names.py + - src/rp2_common/pico_float/include/pico/float.h + - src/rp2_common/pico_double/include/pico/double.h + - test/pico_float_test/custom_float_funcs_test.c + - test/pico_float_test/custom_double_funcs_test.c + +jobs: + check-float-tests: + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Check float tests + run: | + tools/check_float_test_names.py diff --git a/test/pico_float_test/custom_double_funcs_test.c b/test/pico_float_test/custom_double_funcs_test.c index eb4fe92ae..72892ddf9 100644 --- a/test/pico_float_test/custom_double_funcs_test.c +++ b/test/pico_float_test/custom_double_funcs_test.c @@ -35,14 +35,14 @@ static inline double double2ufix_12(int32_t m) { return double2ufix(m, 12); } #endif #if LIB_PICO_DOUBLE_COMPILER || defined(__riscv) -#define double2int_z(f) ({ double _d = f; pico_default_asm_volatile("" : "+r" (_d)); double2 ## int_z(_d); }) -#define double2uint_z(f) ({ double _d = f; pico_default_asm_volatile("" : "+r" (_d)); double2 ## uint_z(_d); }) -#define double2int64_z(f) ({ double _d = f; pico_default_asm_volatile("" : "+r" (_d)); double2 ## int64_z(_d); }) -#define double2uint64_z(f) ({ double _d = f; pico_default_asm_volatile("" : "+r" (_d)); double2 ## uint64_z(_d); }) +#define double2int_z(d) ({ double _d = d; pico_default_asm_volatile("" : "+r" (_d)); double2 ## int_z(_d); }) +#define double2uint_z(d) ({ double _d = d; pico_default_asm_volatile("" : "+r" (_d)); double2 ## uint_z(_d); }) +#define double2int64_z(d) ({ double _d = d; pico_default_asm_volatile("" : "+r" (_d)); double2 ## int64_z(_d); }) +#define double2uint64_z(d) ({ double _d = d; pico_default_asm_volatile("" : "+r" (_d)); double2 ## uint64_z(_d); }) #define int2double(i) ({ int32_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); int2 ## double(_i); }) -#define uint2double(i) ({ uint32_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); uint2 ## double(_i); }) +#define uint2double(u) ({ uint32_t _u = u; pico_default_asm_volatile("" : "+r" (_u)); uint2 ## double(_u); }) #define int642double(i) ({ int64_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); int642 ## double(_i); }) -#define uint642double(i) ({ uint64_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); uint642 ## double(_i); }) +#define uint642double(u) ({ uint64_t _u = u; pico_default_asm_volatile("" : "+r" (_u)); uint642 ## double(_u); }) #endif double make_positive_denormal_double(void) { @@ -117,7 +117,7 @@ int test() { test_checkd(int642double(INT32_MIN+1ll), -2147483647.0, "int642double9"); // todo test correct rounding around maximum precision test_checkd(int642double(INT64_MAX), 9223372036854775807.0, "int642double10"); - test_checkd(int642double(INT64_MIN), -9223372036854775808.0, "int642doubl11e"); + test_checkd(int642double(INT64_MIN), -9223372036854775808.0, "int642double11"); printf("uint642double\n"); test_checkd(uint642double(0), 0.0, "uint642double1"); @@ -147,23 +147,25 @@ int test() { test_checkd(ufix2double(0xa0000000, 30), 2.5, "ufix2double1"); test_checkd(ufix2double(3, -4), 48.0, "ufix2double2"); + printf("fix2double_N\n"); test_checkd(fix2double_8(128), 0.5, "fix2double_8_1"); test_checkd(fix2double_8(-128), -0.5, "fix2double_8_2"); - test_checkd(fix2double_16(8192), 0.125, "fix2double_8_3"); - test_checkd(fix2double_16(-8192), -0.125, "fix2double_8_4"); - test_checkd(fix2double_24(3<<23), 1.5, "fix2double_8_5"); - test_checkd(fix2double_24(-(3<<23)), -1.5, "fix2double_8_6"); + test_checkd(fix2double_16(8192), 0.125, "fix2double_16_1"); + test_checkd(fix2double_16(-8192), -0.125, "fix2double_16_2"); + test_checkd(fix2double_24(3<<23), 1.5, "fix2double_24_1"); + test_checkd(fix2double_24(-(3<<23)), -1.5, "fix2double_24_2"); - test_checkd(ufix2double_8(128), 0.5, "fix2double_8_1"); + printf("ufix2double_N\n"); + test_checkd(ufix2double_8(128), 0.5, "ufix2double_8_1"); test_checkd(ufix2double_8(-128), 16777215.5, "ufix2double_8_2"); - test_checkd(ufix2double_16(8192), 0.125, "ufix2double_8_3"); - test_checkd(ufix2double_16(-8192), 65535.875, "ufix2double_8_4"); - test_checkd(ufix2double_24(3<<23), 1.5, "ufix2double_8_5"); - test_checkd(ufix2double_24(-(3<<23)), 254.5, "ufix2double_8_6"); + test_checkd(ufix2double_16(8192), 0.125, "ufix2double_16_1"); + test_checkd(ufix2double_16(-8192), 65535.875, "ufix2double_16_2"); + test_checkd(ufix2double_24(3<<23), 1.5, "ufix2double_24_1"); + test_checkd(ufix2double_24(-(3<<23)), 254.5, "ufix2double_24_2"); #endif #if PICO_DOUBLE_HAS_FIX64_TO_DOUBLE_CONVERSIONS - printf("fix64double\n"); + printf("fix642double\n"); // todo test correct rounding around maximum precision test_checkd(fix642double(-0xa000000000ll, 38), -2.5, "fix642double1"); test_checkd(fix642double(-3, -34), -51539607552.0, "fix642double2"); @@ -171,7 +173,7 @@ int test() { printf("ufix642double\n"); // todo test correct rounding around maximum precision test_checkd(ufix642double(0xa000000000ll, 38), 2.5, "ufix642double1"); - test_checkd(ufix642double(3, -34), 51539607552.0, "fix64double2"); + test_checkd(ufix642double(3, -34), 51539607552.0, "ufix642double2"); #endif #if PICO_DOUBLE_HAS_DOUBLE_TO_FIX32_M_CONVERSIONS @@ -222,99 +224,99 @@ int test() { test_checku(double2ufix(3.24999, 2), 12, "double2ufix6"); test_checku(double2ufix(3.25, 2), 13, "double2ufix7"); test_checku(double2ufix(3.0, -1), 1, "double2ufix8"); // not very useful - test_checku(double2ufix(0.0, 16), 0, "double2ufix12"); - test_checku(double2ufix(-0.0, 16), 0, "double2ufix13"); - test_checku(double2ufix(0.0, -16), 0, "double2ufix14"); - test_checku(double2ufix(-0.0, -16), 0, "double2ufix15"); + test_checku(double2ufix(0.0, 16), 0, "double2ufix9"); + test_checku(double2ufix(-0.0, 16), 0, "double2ufix10"); + test_checku(double2ufix(0.0, -16), 0, "double2ufix11"); + test_checku(double2ufix(-0.0, -16), 0, "double2ufix12"); u64d.u = 0x7fe0000000012345ull; - test_checku(double2ufix(u64d.d, 0), UINT32_MAX, "double2ufix16a"); - test_checku(double2ufix(u64d.d, 1), UINT32_MAX, "double2ufix16b"); - test_checku(double2ufix(u64d.d, 2), UINT32_MAX, "double2ufix16c"); + test_checku(double2ufix(u64d.d, 0), UINT32_MAX, "double2ufix13a"); + test_checku(double2ufix(u64d.d, 1), UINT32_MAX, "double2ufix13b"); + test_checku(double2ufix(u64d.d, 2), UINT32_MAX, "double2ufix13c"); u64d.u = 0xffe0000000012345ull; - test_checku(double2ufix(u64d.d, 0), 0, "double2ufix17a"); - test_checku(double2ufix(u64d.d, 1), 0, "double2ufix17b"); - test_checku(double2ufix(u64d.d, 2), 0, "double2ufix17c"); + test_checku(double2ufix(u64d.d, 0), 0, "double2ufix14a"); + test_checku(double2ufix(u64d.d, 1), 0, "double2ufix14b"); + test_checku(double2ufix(u64d.d, 2), 0, "double2ufix14c"); #endif #if PICO_DOUBLE_HAS_DOUBLE_TO_FIX64_M_CONVERSIONS printf("double2fix64\n"); - test_checki64(double2fix64(3.5, 8), 0x380, "double2fix641"); - test_checki64(double2fix64(-3.5, 8), -0x380, "double2fix642"); - test_checki64(double2fix64(32768.0, 16), 32768ll << 16, "double2fix643"); - test_checki64(double2fix64(65536.0, 16), 65536ll << 16, "double2fix644"); - test_checki64(double2fix64(2147483648.0, 16), 2147483648ll << 16, "double2fix644b"); - test_checki64(double2fix64(65536.0 * 65536.0 * 32768.0, 16), INT64_MAX, "double2fix644c"); - test_checki64(double2fix64(INFINITY, 16), INT64_MAX, "double2fix645"); - test_checki64(double2fix64(-INFINITY, 16), INT64_MIN, "double2fix645b"); - test_checki64(double2fix64(INFINITY, -16), INT64_MAX, "double2fix645c"); - test_checki64(double2fix64(-INFINITY, -16), INT64_MIN, "double2fix645d"); - test_checki64(double2fix64(INFINITY, 0), INT64_MAX, "double2fix645e"); - test_checki64(double2fix64(-INFINITY, 0), INT64_MIN, "double2fix645f"); - test_checki64(double2fix64(3.24999, 2), 12, "double2fix646"); - test_checki64(double2fix64(3.25, 2), 13, "double2fix647"); - test_checki64(double2fix64(-3.24999, 2), -13, "double2fix648"); - test_checki64(double2fix64(-3.25, 2), -13, "double2fix649"); - test_checki64(double2fix64(-3.0, -1), -2, "double2fix6410"); // not very useful - test_checki64(double2fix64(2147483648.0 * 2147483648.0, 16), INT64_MAX, "double2ufix6411"); - test_checki64(double2fix64(0.0, 16), 0, "double2fix6412"); - test_checki64(double2fix64(-0.0, 16), 0, "double2fix6413"); - test_checki64(double2fix64(0.0, -16), 0, "double2fix6412b"); - test_checki64(double2fix64(-0.0, -16), 0, "double2fix6413b"); - test_checki64(double2fix64(-3.25, 40), -13ll * (1ll << 38), "double2fix6414"); + test_checki64(double2fix64(3.5, 8), 0x380, "double2fix64_1"); + test_checki64(double2fix64(-3.5, 8), -0x380, "double2fix64_2"); + test_checki64(double2fix64(32768.0, 16), 32768ll << 16, "double2fix64_3"); + test_checki64(double2fix64(65536.0, 16), 65536ll << 16, "double2fix64_4"); + test_checki64(double2fix64(2147483648.0, 16), 2147483648ll << 16, "double2fix64_4b"); + test_checki64(double2fix64(65536.0 * 65536.0 * 32768.0, 16), INT64_MAX, "double2fix64_4c"); + test_checki64(double2fix64(INFINITY, 16), INT64_MAX, "double2fix64_5"); + test_checki64(double2fix64(-INFINITY, 16), INT64_MIN, "double2fix64_5b"); + test_checki64(double2fix64(INFINITY, -16), INT64_MAX, "double2fix64_5c"); + test_checki64(double2fix64(-INFINITY, -16), INT64_MIN, "double2fix64_5d"); + test_checki64(double2fix64(INFINITY, 0), INT64_MAX, "double2fix64_5e"); + test_checki64(double2fix64(-INFINITY, 0), INT64_MIN, "double2fix64_5f"); + test_checki64(double2fix64(3.24999, 2), 12, "double2fix64_6"); + test_checki64(double2fix64(3.25, 2), 13, "double2fix64_7"); + test_checki64(double2fix64(-3.24999, 2), -13, "double2fix64_8"); + test_checki64(double2fix64(-3.25, 2), -13, "double2fix64_9"); + test_checki64(double2fix64(-3.0, -1), -2, "double2fix64_10"); // not very useful + test_checki64(double2fix64(2147483648.0 * 2147483648.0, 16), INT64_MAX, "double2fix64_11"); + test_checki64(double2fix64(0.0, 16), 0, "double2fix64_12"); + test_checki64(double2fix64(0.0, -16), 0, "double2fix64_12b"); + test_checki64(double2fix64(-0.0, 16), 0, "double2fix64_13"); + test_checki64(double2fix64(-0.0, -16), 0, "double2fix64_13b"); + test_checki64(double2fix64(-3.25, 40), -13ll * (1ll << 38), "double2fix64_14"); u64d.u = 0xc00a000000000001; - test_checki64(double2fix64(u64d.d, 40), -13ll * (1ll << 38) - 1ll, "double2fix6414b"); + test_checki64(double2fix64(u64d.d, 40), -13ll * (1ll << 38) - 1ll, "double2fix64_14b"); u64d.u = 0xc00a000080000001; - test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18) - 2ll, "double2fix6415c"); + test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18) - 2ll, "double2fix64_14c"); u64d.u = 0xc00a000080000000; - test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18) - 1ll, "double2fix6415d"); + test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18) - 1ll, "double2fix64_14d"); u64d.u = 0xc00a000000000001; - test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18) - 1ll, "double2fix6415e"); + test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18) - 1ll, "double2fix64_14e"); u64d.u = 0xc00a000000000000; - test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18), "double2fix6415g"); + test_checki64(double2fix64(u64d.d, 20), -13ll * (1ll << 18), "double2fix64_14f"); u64d.u = 0xc00a000080000001; - test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17) - 1ll, "double2fix6415h"); + test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17) - 1ll, "double2fix64_14g"); u64d.u = 0xc00a000080000000; - test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17) - 1ll, "double2fix6415i"); + test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17) - 1ll, "double2fix64_14h"); u64d.u = 0xc00a000000000001; - test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17) - 1ll, "double2fix6415j"); + test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17) - 1ll, "double2fix64_14i"); u64d.u = 0xc00a000000000000; - test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17), "double2fix6415k"); + test_checki64(double2fix64(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_14j"); u64d.u = 0x7fe0000000012345ull; - test_checki64(double2fix64(u64d.d, 0), INT64_MAX, "double2fix6416a"); - test_checki64(double2fix64(u64d.d, 1), INT64_MAX, "double2fix6416b"); - test_checki64(double2fix64(u64d.d, 2), INT64_MAX, "double2fix6416c"); + test_checki64(double2fix64(u64d.d, 0), INT64_MAX, "double2fix64_15a"); + test_checki64(double2fix64(u64d.d, 1), INT64_MAX, "double2fix64_15b"); + test_checki64(double2fix64(u64d.d, 2), INT64_MAX, "double2fix64_15c"); u64d.u = 0xffe0000000012345ull; - test_checki64(double2fix64(u64d.d, 0), INT64_MIN, "double2fix6417a"); - test_checki64(double2fix64(u64d.d, 1), INT64_MIN, "double2fix6417b"); - test_checki64(double2fix64(u64d.d, 2), INT64_MIN, "double2fix6417c"); + test_checki64(double2fix64(u64d.d, 0), INT64_MIN, "double2fix64_16a"); + test_checki64(double2fix64(u64d.d, 1), INT64_MIN, "double2fix64_16b"); + test_checki64(double2fix64(u64d.d, 2), INT64_MIN, "double2fix64_16c"); printf("double2ufix64\n"); - test_checku64(double2ufix64(3.5, 8), 0x380, "double2ufix641"); - test_checku64(double2ufix64(-3.5, 8), 0, "double2ufix642"); - test_checku64(double2ufix64(32768.0, 16), 32768ull << 16, "double2ufix643"); - test_checku64(double2ufix64(65536.0, 16), 65536ull << 16, "double2ufix644"); - test_checku64(double2ufix64(2147483648.0, 16), 2147483648ull << 16, "double2ufix644b"); - test_checku64(double2ufix64(INFINITY, 16), UINT64_MAX, "double2ufix645"); - test_checku64(double2ufix64(-INFINITY, 16), 0, "double2ufix645b"); - test_checku64(double2ufix64(INFINITY, -16), UINT64_MAX, "double2ufix645c"); - test_checku64(double2ufix64(-INFINITY, -16), 0, "double2ufix645d"); - test_checku64(double2ufix64(INFINITY, 0), UINT64_MAX, "double2ufix645e"); - test_checku64(double2ufix64(-INFINITY, 0), 0, "double2ufix645f"); - test_checku64(double2ufix64(3.24999, 2), 12, "double2ufix646"); - test_checku64(double2ufix64(3.25, 2), 13, "double2ufix647"); - test_checku64(double2ufix64(3.0, -1), 1, "double2ufix648"); // not very useful - test_checku64(double2ufix64(0.0, 16), 0, "double2ufix649"); - test_checku64(double2ufix64(-0.0, 16), 0, "double2ufix6410"); + test_checku64(double2ufix64(3.5, 8), 0x380, "double2ufix64_1"); + test_checku64(double2ufix64(-3.5, 8), 0, "double2ufix64_2"); + test_checku64(double2ufix64(32768.0, 16), 32768ull << 16, "double2ufix64_3"); + test_checku64(double2ufix64(65536.0, 16), 65536ull << 16, "double2ufix64_4"); + test_checku64(double2ufix64(2147483648.0, 16), 2147483648ull << 16, "double2ufix64_4b"); + test_checku64(double2ufix64(INFINITY, 16), UINT64_MAX, "double2ufix64_5"); + test_checku64(double2ufix64(-INFINITY, 16), 0, "double2ufix64_5b"); + test_checku64(double2ufix64(INFINITY, -16), UINT64_MAX, "double2ufix64_5c"); + test_checku64(double2ufix64(-INFINITY, -16), 0, "double2ufix64_5d"); + test_checku64(double2ufix64(INFINITY, 0), UINT64_MAX, "double2ufix64_5e"); + test_checku64(double2ufix64(-INFINITY, 0), 0, "double2ufix64_5f"); + test_checku64(double2ufix64(3.24999, 2), 12, "double2ufix64_6"); + test_checku64(double2ufix64(3.25, 2), 13, "double2ufix64_7"); + test_checku64(double2ufix64(3.0, -1), 1, "double2ufix64_8"); // not very useful + test_checku64(double2ufix64(0.0, 16), 0, "double2ufix64_9"); + test_checku64(double2ufix64(-0.0, 16), 0, "double2ufix64_10"); u64d.u = 0x7fe0000000012345ull; - test_checku64(double2ufix64(u64d.d, 0), UINT64_MAX, "double2ufix6411a"); - test_checku64(double2ufix64(u64d.d, 1), UINT64_MAX, "double2ufix6411b"); - test_checku64(double2ufix64(u64d.d, 2), UINT64_MAX, "double2ufix6411c"); + test_checku64(double2ufix64(u64d.d, 0), UINT64_MAX, "double2ufix64_11a"); + test_checku64(double2ufix64(u64d.d, 1), UINT64_MAX, "double2ufix64_11b"); + test_checku64(double2ufix64(u64d.d, 2), UINT64_MAX, "double2ufix64_11c"); u64d.u = 0xffe0000000012345ull; - test_checku64(double2ufix64(u64d.d, 0), 0, "double2ufix6412a"); - test_checku64(double2ufix64(u64d.d, 1), 0, "double2ufix6412b"); - test_checku64(double2ufix64(u64d.d, 2), 0, "double2ufix6412c"); + test_checku64(double2ufix64(u64d.d, 0), 0, "double2ufix64_12a"); + test_checku64(double2ufix64(u64d.d, 1), 0, "double2ufix64_12b"); + test_checku64(double2ufix64(u64d.d, 2), 0, "double2ufix64_12c"); #endif #if PICO_DOUBLE_HAS_DOUBLE_TO_FIX32_Z_CONVERSIONS @@ -336,8 +338,8 @@ int test() { test_checki(double2fix_z(-0.75, 1), -1, "double2fix_z10"); test_checki(double2fix_z(-3.0, -1), -1, "double2fix_z11"); // not very useful test_checki(double2fix_z(0.0, 16), 0, "double2fix_z12"); - test_checki(double2fix_z(-0.0, 16), 0, "double2fix_z13"); test_checki(double2fix_z(0.0, -16), 0, "double2fix_z12b"); + test_checki(double2fix_z(-0.0, 16), 0, "double2fix_z13"); test_checki(double2fix_z(-0.0, -16), 0, "double2fix_z13b"); u64d.u = 0x7fe0000000012345ull; test_checki(double2fix_z(u64d.d, 0), INT32_MAX, "double2fix_z14a"); @@ -362,10 +364,10 @@ int test() { test_checku(double2ufix_z(3.24999, 2), 12, "double2ufix_z6"); test_checku(double2ufix_z(3.25, 2), 13, "double2ufix_z7"); test_checku(double2ufix_z(3.0, -1), 1, "double2ufix_z8"); // not very useful - test_checki(double2ufix_z(0.0, 16), 0, "double2ufix_z9"); - test_checki(double2ufix_z(-0.0, 16), 0, "double2ufix_z10"); - test_checki(double2ufix_z(0.0, -16), 0, "double2ufix_z11"); - test_checki(double2ufix_z(-0.0, -16), 0, "double2ufix_z12"); + test_checku(double2ufix_z(0.0, 16), 0, "double2ufix_z9"); + test_checku(double2ufix_z(-0.0, 16), 0, "double2ufix_z10"); + test_checku(double2ufix_z(0.0, -16), 0, "double2ufix_z11"); + test_checku(double2ufix_z(-0.0, -16), 0, "double2ufix_z12"); u64d.u = 0x7fe0000000012345ull; test_checku(double2ufix_z(u64d.d, 0), UINT32_MAX, "double2ufix_z13a"); test_checku(double2ufix_z(u64d.d, 1), UINT32_MAX, "double2ufix_z13b"); @@ -409,16 +411,16 @@ int test() { u64d.u = 0xc00a000000000001; test_checki64(double2fix64_z(u64d.d, 20), -13ll * (1ll << 18), "double2fix64_z15e"); u64d.u = 0xc00a000000000000; - test_checki64(double2fix64_z(u64d.d, 20), -13ll * (1ll << 18), "double2fix64_z15g"); + test_checki64(double2fix64_z(u64d.d, 20), -13ll * (1ll << 18), "double2fix64_z15f"); u64d.u = 0xc00a000080000001; - test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15h"); + test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15g"); u64d.u = 0xc00a000080000000; - test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15i"); + test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15h"); u64d.u = 0xc00a000000000001; - test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15j"); + test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15i"); u64d.u = 0xc00a000000000000; - test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15k"); + test_checki64(double2fix64_z(u64d.d, 19), -13ll * (1ll << 17), "double2fix64_z15j"); u64d.u = 0x7fe0000000012345ull; test_checki64(double2fix64_z(u64d.d, 0), INT64_MAX, "double2fix64_z16a"); test_checki64(double2fix64_z(u64d.d, 1), INT64_MAX, "double2fix64_z16b"); @@ -433,7 +435,7 @@ int test() { test_checku64(double2ufix64_z(-3.5, 8), 0, "double2ufix64_z2"); test_checku64(double2ufix64_z(32768.0, 16), 32768ll << 16, "double2ufix64_z3"); test_checku64(double2ufix64_z(65536.0, 16), 65536ll << 16, "double2ufix64_z4"); - test_checki64(double2ufix64_z(65536.0 * 65536.0 * 65536.0, 16), UINT64_MAX, "double2ufix64_z4b"); + test_checku64(double2ufix64_z(65536.0 * 65536.0 * 65536.0, 16), UINT64_MAX, "double2ufix64_z4b"); test_checku64(double2ufix64_z(INFINITY, 16), UINT64_MAX, "double2ufix64_z5"); test_checku64(double2ufix64_z(-INFINITY, 16), 0, "double2ufix64_z5b"); test_checku64(double2ufix64_z(INFINITY, -16), UINT64_MAX, "double2ufix64_z5c"); @@ -464,8 +466,8 @@ int test() { test_checki(double2int(0.5), 0, "double2int2"); test_checki(double2int(0.75), 0, "double2int2b"); test_checki(double2int(1.0), 1, "double2int3"); - test_checki(double2int(-10.0), -10, "double2int3a"); - test_checki(double2int(-0.0), 0, "double2int3b"); + test_checki(double2int(-10.0), -10, "double2int3b"); + test_checki(double2int(-0.0), 0, "double2int3c"); test_checki(double2int(-0.25), -1, "double2int4"); test_checki(double2int(-0.5), -1, "double2int4b"); test_checki(double2int(-0.75), -1, "double2int5"); @@ -516,53 +518,53 @@ int test() { #if PICO_DOUBLE_HAS_DOUBLE_TO_INT64_M_CONVERSIONS printf("double2int64\n"); - test_checki64(double2int64(0.0), 0, "double2int641"); - test_checki64(double2int64(0.25), 0, "double2int641b"); - test_checki64(double2int64(0.5), 0, "double2int642"); - test_checki64(double2int64(0.75), 0, "double2int642b"); - test_checki64(double2int64(1.0), 1, "double2int643"); - test_checki64(double2int64(-10.0), -10, "double2int643a"); - test_checki64(double2int64(-0.0), 0, "double2int643b"); - test_checki64(double2int64(-0.25), -1, "double2int644"); - test_checki64(double2int64(-0.5), -1, "double2int644b"); - test_checki64(double2int64(-0.75), -1, "double2int645"); - test_checki64(double2int64(-1.0), -1, "double2int645b"); + test_checki64(double2int64(0.0), 0, "double2int64_1"); + test_checki64(double2int64(0.25), 0, "double2int64_1b"); + test_checki64(double2int64(0.5), 0, "double2int64_2"); + test_checki64(double2int64(0.75), 0, "double2int64_2b"); + test_checki64(double2int64(1.0), 1, "double2int64_3"); + test_checki64(double2int64(-10.0), -10, "double2int64_3b"); + test_checki64(double2int64(-0.0), 0, "double2int64_3c"); + test_checki64(double2int64(-0.25), -1, "double2int64_4"); + test_checki64(double2int64(-0.5), -1, "double2int64_4b"); + test_checki64(double2int64(-0.75), -1, "double2int64_5"); + test_checki64(double2int64(-1.0), -1, "double2int64_5b"); // todo test correct rounding around maximum precision - test_checki64(double2int64(2147483647.0), INT32_MAX, "double2int646"); - test_checki64(double2int64(21474836470.0), 21474836470ll, "double2int647"); - test_checki64(double2int64(-2147483648.0), INT32_MIN, "double2int648"); - test_checki64(double2int64(-21474836480.0), -21474836480ll, "double2int649"); - test_checki64(double2int64(-2.5), -3, "double2int6410"); - test_checki64(double2int64(-2.4), -3, "double2int6411"); + test_checki64(double2int64(2147483647.0), INT32_MAX, "double2int64_6"); + test_checki64(double2int64(21474836470.0), 21474836470ll, "double2int64_7"); + test_checki64(double2int64(-2147483648.0), INT32_MIN, "double2int64_8"); + test_checki64(double2int64(-21474836480.0), -21474836480ll, "double2int64_9"); + test_checki64(double2int64(-2.5), -3, "double2int64_10"); + test_checki64(double2int64(-2.4), -3, "double2int64_11"); u64d.u = 0xc000000000000000ull; - test_checki64(double2int64(u64d.d), -2, "double2int6412"); + test_checki64(double2int64(u64d.d), -2, "double2int64_12"); u64d.u = 0xc008000000000000ull; - test_checki64(double2int64(u64d.d), -3, "double2int6412b"); + test_checki64(double2int64(u64d.d), -3, "double2int64_12b"); u64d.u = 0xc000000000000001ull; - test_checki64(double2int64(u64d.d), -3, "double2int6412c"); + test_checki64(double2int64(u64d.d), -3, "double2int64_12c"); u64d.u = 0xc000000080000000ull; - test_checki64(double2int64(u64d.d), -3, "double2int6412d"); + test_checki64(double2int64(u64d.d), -3, "double2int64_12d"); u64d.u = 0xc000000100000000ull; - test_checki64(double2int64(u64d.d), -3, "double2int6412e"); + test_checki64(double2int64(u64d.d), -3, "double2int64_12e"); u64d.u = 0xc000000100000001ull; - test_checki64(double2int64(u64d.d), -3, "double2int6412f"); - test_checki64(double2int64(make_positive_denormal_double()), 0, "double2int6413"); - test_checki64(double2int64(make_negative_denormal_double()), 0, "double2int6414"); + test_checki64(double2int64(u64d.d), -3, "double2int64_12f"); + test_checki64(double2int64(make_positive_denormal_double()), 0, "double2int64_13"); + test_checki64(double2int64(make_negative_denormal_double()), 0, "double2int64_14"); printf("double2uint64\n"); - test_checku64(double2uint64(0.0), 0, "double2uint641"); - test_checku64(double2uint64(0.25), 0, "double2uint642"); - test_checku64(double2uint64(0.5), 0, "double2uint643"); - test_checku64(double2uint64(0.75), 0, "double2uint644"); - test_checku64(double2uint64(1.0), 1, "double2uint645"); - test_checku64(double2uint64(2147483647.0), INT32_MAX, "double2uint646"); - test_checku64(double2uint64(2147483648.0), INT32_MAX+1u, "double2uint647"); + test_checku64(double2uint64(0.0), 0, "double2uint64_1"); + test_checku64(double2uint64(0.25), 0, "double2uint64_2"); + test_checku64(double2uint64(0.5), 0, "double2uint64_3"); + test_checku64(double2uint64(0.75), 0, "double2uint64_4"); + test_checku64(double2uint64(1.0), 1, "double2uint64_5"); + test_checku64(double2uint64(2147483647.0), INT32_MAX, "double2uint64_6"); + test_checku64(double2uint64(2147483648.0), INT32_MAX+1u, "double2uint64_7"); // todo test correct rounding around maximum precision - test_checku64(double2uint64(4294967294.5), 4294967294ull, "double2uint648"); - test_checku64(double2uint64(4294967295.0), 4294967295ull, "double2uint649"); - test_checku64(double2uint64(42949672950.0), 42949672950, "double2uint6410"); - test_checku64(double2uint64(make_positive_denormal_double()), 0, "double2uint6411"); - test_checku64(double2uint64(make_negative_denormal_double()), 0, "double2uint6412"); + test_checku64(double2uint64(4294967294.5), 4294967294ull, "double2uint64_8"); + test_checku64(double2uint64(4294967295.0), 4294967295ull, "double2uint64_9"); + test_checku64(double2uint64(42949672950.0), 42949672950, "double2uint64_10"); + test_checku64(double2uint64(make_positive_denormal_double()), 0, "double2uint64_11"); + test_checku64(double2uint64(make_negative_denormal_double()), 0, "double2uint64_12"); #endif #if PICO_DOUBLE_HAS_DOUBLE_TO_INT32_Z_CONVERSIONS @@ -573,8 +575,8 @@ int test() { test_checki(double2int_z(0.5), 0, "double2int_z2"); test_checki(double2int_z(0.75), 0, "double2int_z2b"); test_checki(double2int_z(1.0), 1, "double2int_z3"); - test_checki(double2int_z(-10.0), -10, "double2int_z3a"); - test_checki(double2int_z(-0.0), 0, "double2int_z3b"); + test_checki(double2int_z(-10.0), -10, "double2int_z3b"); + test_checki(double2int_z(-0.0), 0, "double2int_z3c"); test_checki(double2int_z(-0.25), 0, "double2int_z4"); test_checki(double2int_z(-0.5), 0, "double2int_z4b"); test_checki(double2int_z(-0.75), 0, "double2int_z5"); @@ -624,8 +626,8 @@ int test() { test_checki64(double2int64_z(0.5), 0, "double2int64_z2"); test_checki64(double2int64_z(0.75), 0, "double2int64_z2b"); test_checki64(double2int64_z(1.0), 1, "double2int64_z3"); - test_checki64(double2int64_z(-10.0), -10, "double2int64_z3a"); - test_checki64(double2int64_z(-0.0), 0, "double2int64_z3b"); + test_checki64(double2int64_z(-10.0), -10, "double2int64_z3b"); + test_checki64(double2int64_z(-0.0), 0, "double2int64_z3c"); test_checki64(double2int64_z(-0.25), 0, "double2int64_z4"); test_checki64(double2int64_z(-0.5), 0, "double2int64_z4b"); test_checki64(double2int64_z(-0.75), 0, "double2int64_z5"); diff --git a/test/pico_float_test/custom_float_funcs_test.c b/test/pico_float_test/custom_float_funcs_test.c index 3a93ed553..62e4a1cfb 100644 --- a/test/pico_float_test/custom_float_funcs_test.c +++ b/test/pico_float_test/custom_float_funcs_test.c @@ -44,9 +44,9 @@ static inline float float2ufix_12(int32_t m) { return float2ufix(m, 12); } #define float2int64_z(f) ({ float _f = f; pico_default_asm_volatile("" : FREG (_f)); float2 ## int64_z(_f); }) #define float2uint64_z(f) ({ float _f = f; pico_default_asm_volatile("" : FREG (_f)); float2 ## uint64_z(_f); }) #define int2float(i) ({ int32_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); int2 ## float(_i); }) -#define uint2float(i) ({ uint32_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); uint2 ## float(_i); }) +#define uint2float(u) ({ uint32_t _u = u; pico_default_asm_volatile("" : "+r" (_u)); uint2 ## float(_u); }) #define int642float(i) ({ int64_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); int642 ## float(_i); }) -#define uint642float(i) ({ uint64_t _i = i; pico_default_asm_volatile("" : "+r" (_i)); uint642 ## float(_i); }) +#define uint642float(u) ({ uint64_t _u = u; pico_default_asm_volatile("" : "+r" (_u)); uint642 ## float(_u); }) #endif float make_positive_denormal_float(void) { @@ -243,18 +243,18 @@ int test() { printf("fix2float_N\n"); test_checkf(fix2float_8(128), 0.5f, "fix2float_8_1"); test_checkf(fix2float_8(-128), -0.5f, "fix2float_8_2"); - test_checkf(fix2float_16(8192), 0.125f, "fix2float_8_3"); - test_checkf(fix2float_16(-8192), -0.125f, "fix2float_8_4"); - test_checkf(fix2float_24(3<<23), 1.5f, "fix2float_8_5"); - test_checkf(fix2float_24(-(3<<23)), -1.5f, "fix2float_8_6"); + test_checkf(fix2float_16(8192), 0.125f, "fix2float_16_1"); + test_checkf(fix2float_16(-8192), -0.125f, "fix2float_16_2"); + test_checkf(fix2float_24(3<<23), 1.5f, "fix2float_24_1"); + test_checkf(fix2float_24(-(3<<23)), -1.5f, "fix2float_24_2"); printf("ufix2float_N\n"); test_checkf(ufix2float_8(128), 0.5f, "ufix2float_8_1"); test_checkf(ufix2float_8(-128), 16777216.f, "ufix2float_8_2"); - test_checkf(ufix2float_16(8192), 0.125f, "ufix2floa4t_8_3"); - test_checkf(ufix2float_16(-8192), 65535.875f, "ufix2float_8_4"); - test_checkf(ufix2float_24(3<<23), 1.5f, "ufix2float_8_5"); - test_checkf(ufix2float_24(-(3<<23)), 254.5f, "ufix2float_8_6"); + test_checkf(ufix2float_16(8192), 0.125f, "ufix2float_16_1"); + test_checkf(ufix2float_16(-8192), 65535.875f, "ufix2float_16_2"); + test_checkf(ufix2float_24(3<<23), 1.5f, "ufix2float_24_1"); + test_checkf(ufix2float_24(-(3<<23)), 254.5f, "ufix2float_24_2"); #endif @@ -394,61 +394,59 @@ int test() { #if PICO_FLOAT_HAS_FLOAT_TO_FIX64_M_CONVERSIONS printf("float2fix64\n"); - test_checki64(float2fix64(3.5f, 8), 0x380, "float2fix641"); - test_checki64(float2fix64(-3.5f, 8), -0x380, "float2fix642"); - test_checki64(float2fix64(32768.0f, 16), 32768ll << 16, "float2fix643"); - test_checki64(float2fix64(65536.0f, 16), 65536ll << 16, "float2fix644"); - test_checki64(float2fix64(2147483648.0f, 16), 2147483648ll << 16, "float2fix644b"); - test_checki64(float2fix64(65536.0f * 65536.0f * 32768.0f, 16), INT64_MAX, "float2fix644c"); - test_checki64(float2fix64(INFINITY, 16), INT64_MAX, "float2fix645"); - test_checki64(float2fix64(-INFINITY, 16), INT64_MIN, "float2fix645b"); - test_checki64(float2fix64(INFINITY, -16), INT64_MAX, "float2fix645c"); - test_checki64(float2fix64(-INFINITY, -16), INT64_MIN, "float2fix645d"); - test_checki64(float2fix64(INFINITY, 0), INT64_MAX, "float2fix645e"); - test_checki64(float2fix64(-INFINITY, 0), INT64_MIN, "float2fix645f"); - test_checki64(float2fix64(3.24999f, 2), 12, "float2fix646"); - test_checki64(float2fix64(3.25f, 2), 13, "float2fix647"); - test_checki64(float2fix64(-3.24999f, 2), -13, "float2fix648"); - test_checki64(float2fix64(-3.25f, 2), -13, "float2fix649"); - test_checki64(float2fix64(-3.0f, -1), -2, "float2fix6410"); // not very useful + test_checki64(float2fix64(3.5f, 8), 0x380, "float2fix64_1"); + test_checki64(float2fix64(-3.5f, 8), -0x380, "float2fix64_2"); + test_checki64(float2fix64(32768.0f, 16), 32768ll << 16, "float2fix64_3"); + test_checki64(float2fix64(65536.0f, 16), 65536ll << 16, "float2fix64_4"); + test_checki64(float2fix64(2147483648.0f, 16), 2147483648ll << 16, "float2fix64_4b"); + test_checki64(float2fix64(65536.0f * 65536.0f * 32768.0f, 16), INT64_MAX, "float2fix64_4c"); + test_checki64(float2fix64(INFINITY, 16), INT64_MAX, "float2fix64_5"); + test_checki64(float2fix64(-INFINITY, 16), INT64_MIN, "float2fix64_5b"); + test_checki64(float2fix64(INFINITY, -16), INT64_MAX, "float2fix64_5c"); + test_checki64(float2fix64(-INFINITY, -16), INT64_MIN, "float2fix64_5d"); + test_checki64(float2fix64(INFINITY, 0), INT64_MAX, "float2fix64_5e"); + test_checki64(float2fix64(-INFINITY, 0), INT64_MIN, "float2fix64_5f"); + test_checki64(float2fix64(3.24999f, 2), 12, "float2fix64_6"); + test_checki64(float2fix64(3.25f, 2), 13, "float2fix64_7"); + test_checki64(float2fix64(-3.24999f, 2), -13, "float2fix64_8"); + test_checki64(float2fix64(-3.25f, 2), -13, "float2fix64_9"); + test_checki64(float2fix64(-3.0f, -1), -2, "float2fix64_10"); // not very useful u32f.u = 0x7f012345; - test_checki64(float2fix64(u32f.f, 0), INT64_MAX, "float2fix6411a"); - test_checki64(float2fix64(u32f.f, 1), INT64_MAX, "float2fix6411b"); - test_checki64(float2fix64(u32f.f, 2), INT64_MAX, "float2fix6411c"); + test_checki64(float2fix64(u32f.f, 0), INT64_MAX, "float2fix64_11a"); + test_checki64(float2fix64(u32f.f, 1), INT64_MAX, "float2fix64_11b"); + test_checki64(float2fix64(u32f.f, 2), INT64_MAX, "float2fix64_11c"); u32f.u = 0xff012345; - test_checki64(float2fix64(u32f.f, 0), INT64_MIN, "float2fix6412a"); - test_checki64(float2fix64(u32f.f, 1), INT64_MIN, "float2fix6412b"); - test_checki64(float2fix64(u32f.f, 2), INT64_MIN, "float2fix6412c"); + test_checki64(float2fix64(u32f.f, 0), INT64_MIN, "float2fix64_12a"); + test_checki64(float2fix64(u32f.f, 1), INT64_MIN, "float2fix64_12b"); + test_checki64(float2fix64(u32f.f, 2), INT64_MIN, "float2fix64_12c"); #ifdef float2fix64 #error float2fix64 overridden, so original needs testing #endif printf("float2ufix64\n"); - test_checku64(float2ufix64(3.5f, 8), 0x380, "float2ufix641"); - test_checku64(float2ufix64(-3.5f, 8), 0, "float2ufix642"); - test_checku64(float2ufix64(32768.0f, 16), 32768ull << 16, "float2ufix643"); - test_checku64(float2ufix64(65536.0f, 16), 65536ull << 16, "float2ufix644"); - test_checku64(float2ufix64(2147483648.0f, 16), 2147483648ull << 16, "float2ufix644b"); - test_checku64(float2ufix64(INFINITY, 16), UINT64_MAX, "float2ufix645"); - test_checku64(float2ufix64(-INFINITY, 16), 0, "float2ufix645b"); - test_checku64(float2ufix64(INFINITY, -16), UINT64_MAX, "float2ufix645c"); - test_checku64(float2ufix64(-INFINITY, -16), 0, "float2ufix645d"); - test_checku64(float2ufix64(INFINITY, 0), UINT64_MAX, "float2ufix645e"); - test_checku64(float2ufix64(-INFINITY, 0), 0, "float2ufix645f"); - test_checku64(float2ufix64(INFINITY, 16), UINT64_MAX, "float2ufix645"); - test_checku64(float2ufix64(-INFINITY, 16), 0, "float2ufix645b"); - test_checku64(float2ufix64(3.24999f, 2), 12, "float2ufix646"); - test_checku64(float2ufix64(3.25f, 2), 13, "float2ufix647"); - test_checku64(float2ufix64(3.0f, -1), 1, "float2ufix648"); // not very useful + test_checku64(float2ufix64(3.5f, 8), 0x380, "float2ufix64_1"); + test_checku64(float2ufix64(-3.5f, 8), 0, "float2ufix64_2"); + test_checku64(float2ufix64(32768.0f, 16), 32768ull << 16, "float2ufix64_3"); + test_checku64(float2ufix64(65536.0f, 16), 65536ull << 16, "float2ufix64_4"); + test_checku64(float2ufix64(2147483648.0f, 16), 2147483648ull << 16, "float2ufix64_4b"); + test_checku64(float2ufix64(INFINITY, 16), UINT64_MAX, "float2ufix64_5"); + test_checku64(float2ufix64(-INFINITY, 16), 0, "float2ufix64_5b"); + test_checku64(float2ufix64(INFINITY, -16), UINT64_MAX, "float2ufix64_5c"); + test_checku64(float2ufix64(-INFINITY, -16), 0, "float2ufix64_5d"); + test_checku64(float2ufix64(INFINITY, 0), UINT64_MAX, "float2ufix64_5e"); + test_checku64(float2ufix64(-INFINITY, 0), 0, "float2ufix64_5f"); + test_checku64(float2ufix64(3.24999f, 2), 12, "float2ufix64_6"); + test_checku64(float2ufix64(3.25f, 2), 13, "float2ufix64_7"); + test_checku64(float2ufix64(3.0f, -1), 1, "float2ufix64_8"); // not very useful u32f.u = 0x7f012345; - test_checku64(float2ufix64(u32f.f, 0), UINT64_MAX, "float2ufix649a"); - test_checku64(float2ufix64(u32f.f, 1), UINT64_MAX, "float2ufix649b"); - test_checku64(float2ufix64(u32f.f, 2), UINT64_MAX, "float2ufix649c"); + test_checku64(float2ufix64(u32f.f, 0), UINT64_MAX, "float2ufix64_9a"); + test_checku64(float2ufix64(u32f.f, 1), UINT64_MAX, "float2ufix64_9b"); + test_checku64(float2ufix64(u32f.f, 2), UINT64_MAX, "float2ufix64_9c"); u32f.u = 0xff012345; - test_checku64(float2ufix64(u32f.f, 0), 0, "float2ufix6410a"); - test_checku64(float2ufix64(u32f.f, 1), 0, "float2ufix6410b"); - test_checku64(float2ufix64(u32f.f, 2), 0, "float2ufix6410c"); + test_checku64(float2ufix64(u32f.f, 0), 0, "float2ufix64_10a"); + test_checku64(float2ufix64(u32f.f, 1), 0, "float2ufix64_10b"); + test_checku64(float2ufix64(u32f.f, 2), 0, "float2ufix64_10c"); #ifdef float2ufix64 #error float2ufix64 overridden, so original needs testing @@ -624,8 +622,8 @@ int test() { test_checki(float2int(0.5f), 0, "float2int2"); test_checki(float2int(0.75f), 0, "float2int2b"); test_checki(float2int(1.0f), 1, "float2int3"); - test_checki(float2int(-10.0f), -10, "float2int3a"); - test_checki(float2int(-0.0f), 0, "float2int3b"); + test_checki(float2int(-10.0f), -10, "float2int3b"); + test_checki(float2int(-0.0f), 0, "float2int3c"); test_checki(float2int(-0.25f), -1, "float2int4"); test_checki(float2int(-0.5f), -1, "float2int4b"); test_checki(float2int(-0.75f), -1, "float2int5"); @@ -659,40 +657,40 @@ int test() { #if PICO_FLOAT_HAS_FLOAT_TO_INT64_M_CONVERSIONS printf("float2int64\n"); - test_checki64(float2int64(0.0f), 0, "float2int641"); - test_checki64(float2int64(0.25f), 0, "float2int641b"); - test_checki64(float2int64(0.5f), 0, "float2int642"); - test_checki64(float2int64(0.75f), 0, "float2int642b"); - test_checki64(float2int64(1.0f), 1, "float2int643"); - test_checki64(float2int64(-10.0f), -10, "float2int643a"); - test_checki64(float2int64(-0.0f), 0, "float2int643b"); - test_checki64(float2int64(-0.25f), -1, "float2int644"); - test_checki64(float2int64(-0.5f), -1, "float2int644b"); - test_checki64(float2int64(-0.75f), -1, "float2int645"); - test_checki64(float2int64(-1.0f), -1, "float2int645b"); + test_checki64(float2int64(0.0f), 0, "float2int64_1"); + test_checki64(float2int64(0.25f), 0, "float2int64_1b"); + test_checki64(float2int64(0.5f), 0, "float2int64_2"); + test_checki64(float2int64(0.75f), 0, "float2int64_2b"); + test_checki64(float2int64(1.0f), 1, "float2int64_3"); + test_checki64(float2int64(-10.0f), -10, "float2int64_3b"); + test_checki64(float2int64(-0.0f), 0, "float2int64_3c"); + test_checki64(float2int64(-0.25f), -1, "float2int64_4"); + test_checki64(float2int64(-0.5f), -1, "float2int64_4b"); + test_checki64(float2int64(-0.75f), -1, "float2int64_5"); + test_checki64(float2int64(-1.0f), -1, "float2int64_5b"); // todo test correct rounding around maximum precision - test_checki64(float2int64(2147483647.0f), INT32_MAX+1ll, "float2int646"); - test_checki64(float2int64(21474836470.0f), 21474836480ll, "float2int647"); // note loss of precision - test_checki64(float2int64(-2147483648.0f), INT32_MIN, "float2int648"); - test_checki64(float2int64(-21474836480.0f), -21474836480ll, "float2int649"); - test_checki64(float2int64(-2.5f), -3, "float2int6410"); - test_checki64(float2int64(-2.4f), -3, "float2int6411"); + test_checki64(float2int64(2147483647.0f), INT32_MAX+1ll, "float2int64_6"); + test_checki64(float2int64(21474836470.0f), 21474836480ll, "float2int64_7"); // note loss of precision + test_checki64(float2int64(-2147483648.0f), INT32_MIN, "float2int64_8"); + test_checki64(float2int64(-21474836480.0f), -21474836480ll, "float2int64_9"); + test_checki64(float2int64(-2.5f), -3, "float2int64_10"); + test_checki64(float2int64(-2.4f), -3, "float2int64_11"); #ifdef float2uint64 #error float2uint64 overridden, so original needs testing #endif printf("float2uint64\n"); - test_checku64(float2uint64(0.0f), 0, "float2uint641"); - test_checku64(float2uint64(0.25f), 0, "float2uint642"); - test_checku64(float2uint64(0.5f), 0, "float2uint643"); - test_checku64(float2uint64(0.75f), 0, "float2uint644"); - test_checku64(float2uint64(1.0f), 1, "float2uint645"); - test_checku64(float2uint64(2147483647.0f), INT32_MAX+1u, "float2uint646"); // note loss of precision - test_checku64(float2uint64(2147483648.0f), INT32_MAX+1u, "float2uint647"); - test_checku64(float2uint64(4294967294.5f), 4294967296ull, "float2uint648"); // note loss of precision - test_checku64(float2uint64(4294967295.0f), 4294967296ull, "float2uint649"); // note loss of precision - test_checku64(float2uint64(42949672950.0f), 42949672960ull, "float2uint6410"); // note loss of precision + test_checku64(float2uint64(0.0f), 0, "float2uint64_1"); + test_checku64(float2uint64(0.25f), 0, "float2uint64_2"); + test_checku64(float2uint64(0.5f), 0, "float2uint64_3"); + test_checku64(float2uint64(0.75f), 0, "float2uint64_4"); + test_checku64(float2uint64(1.0f), 1, "float2uint64_5"); + test_checku64(float2uint64(2147483647.0f), INT32_MAX+1u, "float2uint64_6"); // note loss of precision + test_checku64(float2uint64(2147483648.0f), INT32_MAX+1u, "float2uint64_7"); + test_checku64(float2uint64(4294967294.5f), 4294967296ull, "float2uint64_8"); // note loss of precision + test_checku64(float2uint64(4294967295.0f), 4294967296ull, "float2uint64_9"); // note loss of precision + test_checku64(float2uint64(42949672950.0f), 42949672960ull, "float2uint64_10"); // note loss of precision #endif // // These methods round towards 0. @@ -704,8 +702,8 @@ int test() { test_checki(float2int_z(0.5f), 0, "float2int_z2"); test_checki(float2int_z(0.75f), 0, "float2int_z2b"); test_checki(float2int_z(1.0f), 1, "float2int_z3"); - test_checki(float2int_z(-10.0f), -10, "float2int_z3a"); - test_checki(float2int_z(-0.0f), 0, "float2int_z3b"); + test_checki(float2int_z(-10.0f), -10, "float2int_z3b"); + test_checki(float2int_z(-0.0f), 0, "float2int_z3c"); test_checki(float2int_z(-0.25f), 0, "float2int_z4"); test_checki(float2int_z(-0.5f), 0, "float2int_z4b"); test_checki(float2int_z(-0.75f), 0, "float2int_z5"); @@ -731,8 +729,8 @@ int test() { test_checki(call_float2int_z(0.5f), 0, "call_float2int_z2"); test_checki(call_float2int_z(0.75f), 0, "call_float2int_z2b"); test_checki(call_float2int_z(1.0f), 1, "call_float2int_z3"); - test_checki(call_float2int_z(-10.0f), -10, "call_float2int_z3a"); - test_checki(call_float2int_z(-0.0f), 0, "call_float2int_z3b"); + test_checki(call_float2int_z(-10.0f), -10, "call_float2int_z3b"); + test_checki(call_float2int_z(-0.0f), 0, "call_float2int_z3c"); test_checki(call_float2int_z(-0.25f), 0, "call_float2int_z4"); test_checki(call_float2int_z(-0.5f), 0, "call_float2int_z4b"); test_checki(call_float2int_z(-0.75f), 0, "call_float2int_z5"); @@ -748,7 +746,7 @@ int test() { test_checki(call_float2int_z(make_negative_denormal_float()), 0, "call_float2int_z13"); #endif - printf("float2uint_z\n"); + printf("float2uint_z\n"); test_checku(float2uint_z(0.0f), 0, "float2uint_z1"); test_checku(float2uint_z(0.25f), 0, "float2uint_z2"); test_checku(float2uint_z(0.5f), 0, "float2uint_z3"); @@ -792,8 +790,8 @@ int test() { test_checki64(float2int64_z(0.5f), 0, "float2int64_z2"); test_checki64(float2int64_z(0.75f), 0, "float2int64_z2b"); test_checki64(float2int64_z(1.0f), 1, "float2int64_z3"); - test_checki64(float2int64_z(-10.0f), -10, "float2int64_z3a"); - test_checki64(float2int64_z(-0.0f), 0, "float2int64_z3b"); + test_checki64(float2int64_z(-10.0f), -10, "float2int64_z3b"); + test_checki64(float2int64_z(-0.0f), 0, "float2int64_z3c"); test_checki64(float2int64_z(-0.25f), 0, "float2int64_z4"); test_checki64(float2int64_z(-0.5f), 0, "float2int64_z4b"); test_checki64(float2int64_z(-0.75f), 0, "float2int64_z5"); diff --git a/tools/check_float_test_names.py b/tools/check_float_test_names.py new file mode 100755 index 000000000..34130851d --- /dev/null +++ b/tools/check_float_test_names.py @@ -0,0 +1,330 @@ +#!/usr/bin/env python3 + +import os +import re +import sys +from collections import namedtuple +from dataclasses import dataclass + +ENFORCE_SEQUENTIAL_SUFFIXES = True # if False, allow "double2ufix8" to be followed by "double2ufix12" +ENFORCE_UNDERSCORE_IN_SUFFIX_IF_FUNCTION_ENDS_WITH_NUMBER = True # if False, allow "float2fix641" +ALLOW_TEST_SUFFIXES_TO_START_AT_ZERO = True # if False, don't allow "float2fix0" +ALLOW_TEST_SUFFIXES_TO_SKIP_A = True # if False, don't allow "float2int1b" to follow "float2int1" + +Check = namedtuple("Check", ("test_type", "header_file", "tests_file")) + +CHECKS = ( + Check("float", "src/rp2_common/pico_float/include/pico/float.h", "test/pico_float_test/custom_float_funcs_test.c"), + Check("double", "src/rp2_common/pico_double/include/pico/double.h", "test/pico_float_test/custom_double_funcs_test.c"), +) + +CONVERSION_TYPES = set(( + # integral types + "int", "uint", "int64", "uint64", + # floating-point types + "float", "double", + # fixed-point types + "fix", "ufix", "fix64", "ufix64", + # integral types that round towards zero + "int_z", "uint_z", "int64_z", "uint64_z", + # fixed-point types that round towards zero + "fix_z", "ufix_z", "fix64_z", "ufix64_z", + # other "types" used in the test functions + "float_8", "float_12", "float_16", "float_24", "float_28", "float_32", + "double_8", "double_12", "double_16", "double_24", "double_28", "double_32", + "fix_12", "ufix_12", +)) + +if ENFORCE_SEQUENTIAL_SUFFIXES: + @dataclass + class ConversionFunc: + name: str + from_type: str + to_type: str + num_input_args: int + tested: bool = False + last_test: str = "" + last_test_suffix: str = "" +else: + @dataclass + class ConversionFunc: + name: str + from_type: str + to_type: str + num_input_args: int + tested: bool = False + +def add_conversion_function(conversion_functions, conversion_function, from_type, to_type, num_input_args, filename, lineno): + if conversion_function in conversion_functions: + raise Exception(f"{filename}:{lineno} Conversion function {conversion_function} appears twice") + else: + if from_type not in CONVERSION_TYPES: + raise Exception(f"{filename}:{lineno} Conversion function {conversion_function} converts from unknown type {from_type}") + if to_type not in CONVERSION_TYPES: + raise Exception(f"{filename}:{lineno} Conversion function {conversion_function} converts to unknown type {to_type}") + conversion_functions[conversion_function] = ConversionFunc(conversion_function, from_type, to_type, num_input_args) + +@dataclass +class TestMacro: + name: str + short_type: str + used: bool = False + +def add_test_macro(test_macros, test_macro, short_type, filename, lineno): + if test_macro in test_macros: + raise Exception(f"{filename}:{lineno} Test macro {test_macro} defined twice") + else: + test_macros[test_macro] = TestMacro(test_macro, short_type) + +@dataclass +class FunctionGroup: + name: str + lineno: int + from_type: str + to_type: str + used: bool = False + +def add_function_group(function_groups, function_group, from_type, to_type, filename, lineno): + if function_group in function_groups: + raise Exception(f"{filename}:{lineno} Function group {function_group} appears twice") + else: + function_groups[function_group] = FunctionGroup(function_group, lineno, from_type, to_type) + +def suffix_greater(suffix1, suffix2): + if suffix1 == suffix2: + raise Exception(f"Identical suffixes {suffix1}") + if suffix2 == "": + return True + else: + m1 = re.match(r"^(\d+)([a-z])?$", suffix1) + num1 = int(m1.group(1)) + alpha1 = m1.group(2) + m2 = re.match(r"^(\d+)([a-z])?$", suffix2) + num2 = int(m2.group(1)) + alpha2 = m2.group(2) + if num1 > num2: + return True + elif num1 < num2: + return False + else: # num1 == num2 + if alpha2 is None and alpha1 is not None: + return True + else: + return alpha1 > alpha2 + +def suffix_one_more_than(suffix1, suffix2): + if suffix1 == suffix2: + raise Exception(f"Identical suffixes {suffix1}") + m1 = re.match(r"^(\d+)([a-z])?$", suffix1) + num1 = int(m1.group(1)) + alpha1 = m1.group(2) + if suffix2 == "": + if ALLOW_TEST_SUFFIXES_TO_START_AT_ZERO: + return num1 in (0, 1) and (alpha1 is None or alpha1 == "a") + else: + return num1 == 1 and (alpha1 is None or alpha1 == "a") + else: + m2 = re.match(r"^(\d+)([a-z])?$", suffix2) + num2 = int(m2.group(1)) + alpha2 = m2.group(2) + if num1 > num2: + return num1 - num2 == 1 and (alpha1 is None or alpha1 == "a") + elif num1 < num2: + return False + else: # num1 == num2 + if alpha2 is None and alpha1 is not None: + if ALLOW_TEST_SUFFIXES_TO_SKIP_A: + return alpha1 == "b" + else: + return False + else: + return ord(alpha1) - ord(alpha2) == 1 + +def type_to_short_type(t): + assert(t in CONVERSION_TYPES) + if t in ("int", "fix", "int_z", "fix_z") or t.startswith("fix_"): + return "i" + elif t in ("uint", "ufix", "uint_z", "ufix_z") or t.startswith("ufix_"): + return "u" + elif t in ("int64", "fix64", "int64_z", "fix64_z"): + return "i64" + elif t in ("uint64", "ufix64", "uint64_z", "ufix64_z"): + return "u64" + elif t == "float" or t.startswith("float_"): + return "f" + elif t == "double" or t.startswith("double_"): + return "d" + else: + raise Exception(f"Couldn't determine short_type for {t}") + + +if __name__ == "__main__": + for check in CHECKS: + conversion_functions = dict() + with open(check.header_file) as fh: + #print(f"Reading {check.header_file}") + for lineno, line in enumerate(fh.readlines()): + lineno += 1 + line = line.strip() + # strip trailing comments + line = re.sub(r"\s*//.*$", "", line) + if line: + if m := re.match(r"^\w+ ((\w+)2(\w+))\(([^\)]+)\);$", line): + conversion_function = m.group(1) + from_type = m.group(2) + to_type = m.group(3) + num_input_args = len(m.group(4).split(",")) + #print(lineno, line, conversion_function) + add_conversion_function(conversion_functions, conversion_function, from_type, to_type, num_input_args, check.header_file, lineno) + + test_macros = dict() + function_groups = dict() + last_function_group = None + test_names = set() + + def _check_test(filename, lineno, line, test_macro, function, num_input_args, compare_val, to_type, test_name): + #print(lineno, line, test_macro, function, num_input_args, compare_val, test_name) + if test_macro not in test_macros: + raise Exception(f"{filename}:{lineno} Trying to use unknown test macro {test_macro}") + else: + test_macros[test_macro].used = True + short_type = type_to_short_type(to_type) + expected_macro = "test_check" + short_type + if test_macro != expected_macro: + raise Exception(f"{filename}:{lineno} {test_name} tests {function} which returns {to_type}, so expected it to be checked with {expected_macro} (not {test_macro})") + if function not in conversion_functions: + raise Exception(f"{filename}:{lineno} Trying to use unknown conversion function {function}") + else: + conversion_functions[function].tested = True + if num_input_args != conversion_functions[function].num_input_args: + raise Exception(f"{filename}:{lineno} {num_input_args} arguments were passed to {function} which only expects {conversion_functions[function].num_input_args} arguments") + function_group = re.sub(r"_(\d+)$", "_N", function) + if function_group not in function_groups: + raise Exception(f"{filename}:{lineno} Unexpected function group {function_group}") + else: + function_groups[function_group].used = True + if function_group != last_function_group: + raise Exception(f"{filename}:{lineno} Function group {function_group} doesn't match {last_function_group} on line {function_groups[last_function_group].lineno}") + expected_prefix = function + if not test_name.startswith(expected_prefix): + raise Exception(f"{filename}:{lineno} {test_name} tests {function}, so expected it to start with {expected_prefix}") + if ENFORCE_UNDERSCORE_IN_SUFFIX_IF_FUNCTION_ENDS_WITH_NUMBER: + if re.search(r"\d$", function): + expected_prefix += "_" + if not test_name.startswith(expected_prefix): + raise Exception(f"{filename}:{lineno} {function} ends with a number, so expected the test name ({test_name}) to start with {expected_prefix}") + if test_name in test_names: + raise Exception(f"{filename}:{lineno} Duplicate test name {test_name}") + test_names.add(test_name) + if ENFORCE_UNDERSCORE_IN_SUFFIX_IF_FUNCTION_ENDS_WITH_NUMBER: + test_suffix = re.sub(f"^{re.escape(expected_prefix)}", "", test_name) + else: + test_suffix = re.sub(f"^{re.escape(expected_prefix)}_?", "", test_name) + if not re.match(r"^\d+([a-z])?$", test_suffix): + raise Exception(f"{filename}:{lineno} {test_name} has suffix {test_suffix} which doesn't match the expected pattern of a number followed by an optional letter") + if ENFORCE_SEQUENTIAL_SUFFIXES: + if not suffix_greater(test_suffix, conversion_functions[function].last_test_suffix): + raise Exception(f"{filename}:{lineno} {test_name} follows {conversion_functions[function].last_test} but has a smaller suffix") + if not suffix_one_more_than(test_suffix, conversion_functions[function].last_test_suffix): + if conversion_functions[function].last_test_suffix == "": + raise Exception(f"{filename}:{lineno} {test_name} is the first test in group {function_group} so expected a suffix of 1 (or 1a), not {test_suffix}") + elif test_suffix == conversion_functions[function].last_test_suffix + "a": + raise Exception(f"{filename}:{lineno} {test_name} uses suffix {test_suffix} which can't follow suffix {conversion_functions[function].last_test_suffix}") + else: + raise Exception(f"{filename}:{lineno} {test_name} follows {conversion_functions[function].last_test} but the jump from {conversion_functions[function].last_test_suffix} to {test_suffix} is bigger than one") + conversion_functions[function].last_test = test_name + conversion_functions[function].last_test_suffix = test_suffix + + with open(check.tests_file) as fh: + #print(f"Reading {check.tests_file}") + for lineno, line in enumerate(fh.readlines()): + lineno += 1 + line = line.strip() + # strip trailing comments + line = re.sub(r"\s*//.*$", "", line) + if line: + if m := re.match(r"^#define (test_check(\w+))\(", line): + test_macro = m.group(1) + short_type = m.group(2) + #print(lineno, line, test_macro) + add_test_macro(test_macros, test_macro, short_type, check.tests_file, lineno) + elif m := re.match(r"^#define ((\w+)2(\w+))\(([^\)]+)\)", line): + conversion_function = m.group(1) + from_type = m.group(2) + to_type = m.group(3) + num_input_args = len(m.group(4).split(",")) + #print(lineno, line, conversion_function) + if conversion_function not in conversion_functions: + raise Exception(f"{check.tests_file}:{lineno} {conversion_function} has no counterpart in {check.header_file}") + else: + if num_input_args != conversion_functions[conversion_function].num_input_args: + raise Exception(f"{check.tests_file}:{lineno} {conversion_function} has a different number of arguments to the counterpart in {check.header_file}") + elif m := re.match(r"^\w+ __attribute__\(\(naked\)\) (call_((\w+)2(\w+)))\(([^\)]+)\)", line): + conversion_function = m.group(1) + base_function = m.group(2) + from_type = m.group(3) + to_type = m.group(4) + num_input_args = len(m.group(5).split(",")) + #print(lineno, line, conversion_function) + if base_function not in conversion_functions: + raise Exception(f"{check.tests_file}:{lineno} {conversion_function} exists but {base_function} doesn't exist") + else: + if num_input_args != conversion_functions[base_function].num_input_args: + raise Exception(f"{check.tests_file}:{lineno} {conversion_function} has a different number of arguments to {base_function}") + add_conversion_function(conversion_functions, conversion_function, from_type, to_type, num_input_args, check.tests_file, lineno) + elif m := re.match(r"^static inline (?:float|double) ((\w+)2(\w+_\d+))\(([^\)]+)\)", line): + conversion_function = m.group(1) + from_type = m.group(2) + to_type = m.group(3) + num_input_args = len(m.group(4).split(",")) + #print(lineno, line, conversion_function) + m = re.match(r"^static inline (?:float|double) (\w+2\w+)_\d+\(", line) + base_function = m.group(1) + if base_function not in conversion_functions: + raise Exception(f"{check.tests_file}:{lineno} {conversion_function} exists but {base_function} doesn't exist") + add_conversion_function(conversion_functions, conversion_function, from_type, to_type, num_input_args, check.tests_file, lineno) + elif m := re.match(r"^printf\(\"((\w+)2(\w+))\\n\"\);$", line): + function_group = m.group(1) + from_type = m.group(2) + to_type = m.group(3) + #print(lineno, line, function_group) + if not function_group.endswith("_N"): + if function_group not in conversion_functions: + raise Exception(f"{check.tests_file}:{lineno} Function group {function_group} has no corresponding conversion function") + add_function_group(function_groups, function_group, from_type, to_type, check.tests_file, lineno) + last_function_group = function_group + elif m := re.match(r"^(test_\w+)\(((\w+?)2(\w+))\(([^\)]+(?:\(.*?\))?)\), ([^,]+), \"(\w+)\"\);$", line): + test_macro = m.group(1) + function = m.group(2) + from_type = m.group(3) + to_type = m.group(4) + num_input_args = len(m.group(5).split(",")) + compare_val = m.group(6) + test_name = m.group(7) + _check_test(check.tests_file, lineno, line, test_macro, function, num_input_args, compare_val, to_type, test_name) + elif m:= re.match(r"^(test_\w+)\(((double)2(int))20, ([^,]+), \"(\w+)\"\);$", line): + # special-case, because it uses a stored value rather than an inline conversion + test_macro = m.group(1) + function = m.group(2) + from_type = m.group(3) + to_type = m.group(4) + num_input_args = 1 + compare_val = m.group(5) + test_name = m.group(6) + _check_test(check.tests_file, lineno, line, test_macro, function, num_input_args, compare_val, to_type, test_name) + elif line.startswith("test_"): + raise Exception(f"{check.tests_file}:{lineno} It looks like '{line}' wasn't checked by {os.path.basename(sys.argv[0])}") + #else: + # print(lineno, line) + #print(sorted(conversion_functions.keys())) + #print(sorted(test_macros.keys())) + untested_conversion_functions = list(filter(lambda f: f.tested == False, conversion_functions.values())) + if untested_conversion_functions: + print(f"The following {check.test_type} functions are untested: {sorted(f.name for f in untested_conversion_functions)}") + unused_test_macros = list(filter(lambda m: m.used == False, test_macros.values())) + if unused_test_macros: + print(f"The following {check.test_type} test macros weren't used: {sorted(m.name for m in unused_test_macros)}") + unused_function_groups = list(filter(lambda g: g.used == False, function_groups.values())) + if unused_function_groups: + print(f"The following {check.test_type} function groups didn't contain any tests: {sorted(m.name for m in unused_function_groups)}") +